library(ggplot2)
library(dplyr)
library(stats)

True value in set1, sim1

TrueValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[1, 2])), ", ")[[1]]
#average <- mean(TrueValues_set1)
plot(TrueValue_set1, type = "l", pch = 16, col = "blue", main = "True Values in sim0", xlab = "Iteration", ylab = "Value")

#TrueValue_set1_sim0 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[1, 2])), ", ")[[1]]
#unlist(aggregated_results_1[1, 2])
#clean_str = gsub("\\[|\\]", "", TrueValue_sim0)
#TrueValue_set1_sim1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[2, 2])), ", ")[[1]]

#print(Values)
#X <- 1:100
#plot(TrueValue_set1_sim0, type = "l", pch = 16, col = "blue", main = "True Values in sim0", xlab = "Iteration", ylab = "Value")
#plot(TrueValue_set1_sim1, type = "l", pch = 16, col = "blue", main = "True Values in sim1", xlab = "Iteration", ylab = "Value")

#fit <- lm(Values ~ X)
#abline(fit, col = "red")

True values in set 1, all sim

# Initialize an empty vector to store the True values
TrueValues_set1 <- numeric()

# Loop through each iteration (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_1 dataframe
  TrueValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 2])), ", ")[[1]]
  
  # Append the True values to the vector
  TrueValues_set1 <- c(TrueValues_set1, as.numeric(TrueValue_set1))
}

# Calculate the average of True values
average <- mean(TrueValues_set1)

# Plot the average
plot(TrueValues_set1, type = "l", pch = 16, col = "blue", main = "True Values in set 1", xlab = "Iteration", ylab = "Value")

# Add a horizontal line for the average
abline(h = average, col = "red", lwd = 2)

Expected value in set1, all sim

# Initialize an empty vector to store the True values
ExpectedValues_set1 <- numeric()

# Loop through each iteration (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_1 dataframe
  ExpectedValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 3])), ", ")[[1]]
  
  # Append the True values to the vector
  ExpectedValues_set1 <- c(ExpectedValues_set1, as.numeric(ExpectedValue_set1))
}

# Calculate the average of True values
average <- mean(ExpectedValues_set1)

# Plot the average
plot(ExpectedValues_set1, type = "l", pch = 16, col = "blue", main = "Expected Values in set 1", xlab = "Iteration", ylab = "Value")

# Add a horizontal line for the average
abline(h = average, col = "red", lwd = 2)

True and Expected Values in set 1

# Initialize empty vectors to store true and expected values
TrueValues_set1 <- numeric()
ExpectedValues_set1 <- numeric()

# Loop through each iteration (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_1 dataframe
  TrueValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 2])), ", ")[[1]]
  
  # Extract Expected values from the aggregated_results_1 dataframe
  ExpectedValue_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 3])), ", ")[[1]]
  
  # Append the True and Expected values to their respective vectors
  TrueValues_set1 <- c(TrueValues_set1, as.numeric(TrueValue_set1))
  ExpectedValues_set1 <- c(ExpectedValues_set1, as.numeric(ExpectedValue_set1))
}

# Calculate the average of True values
average_true <- mean(TrueValues_set1)

# Calculate the average of Expected values
average_expected <- mean(ExpectedValues_set1)

# Plot True and Expected values on the same plot
plot(TrueValues_set1, type = "l", pch = 16, col = "blue", main = "True vs Expected Values in set 1", xlab = "Iteration", ylab = "Value")
lines(ExpectedValues_set1, type = "l", pch = 16, col = "red")

# Add legend
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Add horizontal lines for the averages
abline(h = average_true, col = "blue", lwd = 1)
abline(h = average_expected, col = "red", lwd = 1)

Bids in set1, sim1

Bids_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[1, 4])), ", ")[[1]]
#average <- mean(TrueValues_set1)
plot(Bids_set1, type = "l", pch = 16, col = "blue", main = "True Values in sim0", xlab = "Iteration", ylab = "Value")

Bids in set 1, all sim

# Initialize an empty vector to store the True values
Bids_set1 <- numeric()

# Loop through each iteration (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_1 dataframe
  Bid_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 4])), ", ")[[1]]
  
  # Append the True values to the vector (corrected typo)
  Bids_set1 <- c(Bids_set1, as.numeric(Bid_set1))
}

# Check if the vector is properly populated
#print(Bids_set1)

# Calculate the average of True values
average <- mean(Bids_set1, na.rm = TRUE)

# Plot the values
plot(Bids_set1, type = "l", pch = 16, col = "blue", main = "Expected Values in set 1", xlab = "Iteration", ylab = "Value")

# Add a horizontal line for the average
abline(h = average, col = "red", lwd = 2)

Bids and Asks Overall

# Initialize empty vectors to store the Bid and Ask values
Bids_set1 <- numeric()
Asks_set1 <- numeric()

# Loop through each iteration (n)
for (n in 1:10) {
  # Extract Bid values from the aggregated_results_1 dataframe
  Bid_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 4])), ", ")[[1]]
  
  # Extract Ask values from the aggregated_results_1 dataframe (next column)
  Ask_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 5])), ", ")[[1]]
  
  # Append the Bid and Ask values to their respective vectors
  Bids_set1 <- c(Bids_set1, as.numeric(Bid_set1))
  Asks_set1 <- c(Asks_set1, as.numeric(Ask_set1))
}

# Calculate the average of Bid and Ask values
average_bids <- mean(Bids_set1, na.rm = TRUE)
average_asks <- mean(Asks_set1, na.rm = TRUE)

# Plot the Bid and Ask values on the same plot
plot(Bids_set1, type = "l", pch = 16, col = "blue", main = "Bids vs Asks in set 1", xlab = "Iteration", ylab = "Value")
lines(Asks_set1, type = "l", pch = 16, col = "red")

# Add legend
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Add horizontal lines for the averages
abline(h = average_bids, col = "blue", lty = 1)
abline(h = average_asks, col = "red", lty = 1)

Start From Here

set 1 (6 informed)

# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  TrueValues_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 2])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  ExpectedValues_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 3])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    True_values <- sapply(TrueValues_set1, function(x) as.numeric(x[i]))
    Expected_values <- sapply(ExpectedValues_set1, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_true[i, n] <- mean(True_values, na.rm = TRUE)
    average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  Bids_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 4])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  Asks_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 5])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    Bids <- sapply(Bids_set1, function(x) as.numeric(x[i]))
    Asks <- sapply(Asks_set1, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_bid[i, n] <- mean(Bids, na.rm = TRUE)
    average_ask[i, n] <- mean(Asks, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed5_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed6_pnl <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 6])), ", ")

  Informed1_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 8])), ", ")
  
  Informed2_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 10])), ", ")
  
  Informed3_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 12])), ", ")
  
  Informed4_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 14])), ", ")
  
  Informed5_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 16])), ", ")
  
  Informed6_pnl_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 18])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pnl <- sapply(MM_pnl_set1, function(x) as.numeric(x[i]))
    Informed1_pnl <- sapply(Informed1_pnl_set1, function(x) as.numeric(x[i]))
    Informed2_pnl <- sapply(Informed2_pnl_set1, function(x) as.numeric(x[i]))
    Informed3_pnl <- sapply(Informed3_pnl_set1, function(x) as.numeric(x[i]))
    Informed4_pnl <- sapply(Informed4_pnl_set1, function(x) as.numeric(x[i]))
    Informed5_pnl <- sapply(Informed5_pnl_set1, function(x) as.numeric(x[i]))
    Informed6_pnl <- sapply(Informed6_pnl_set1, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
    average_Informed1_pnl[i, n] <- mean(Informed1_pnl, na.rm = TRUE)
    average_Informed2_pnl[i, n] <- mean(Informed2_pnl, na.rm = TRUE)
    average_Informed3_pnl[i, n] <- mean(Informed3_pnl, na.rm = TRUE)
    average_Informed4_pnl[i, n] <- mean(Informed4_pnl, na.rm = TRUE)
    average_Informed5_pnl[i, n] <- mean(Informed5_pnl, na.rm = TRUE)
    average_Informed6_pnl[i, n] <- mean(Informed6_pnl, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed1_pnl <- rowMeans(average_Informed1_pnl, na.rm = TRUE)
overall_average_Informed2_pnl <- rowMeans(average_Informed2_pnl, na.rm = TRUE)
overall_average_Informed3_pnl <- rowMeans(average_Informed3_pnl, na.rm = TRUE)
overall_average_Informed4_pnl <- rowMeans(average_Informed4_pnl, na.rm = TRUE)
overall_average_Informed5_pnl <- rowMeans(average_Informed5_pnl, na.rm = TRUE)
overall_average_Informed6_pnl <- rowMeans(average_Informed6_pnl, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed1_pnl, overall_average_Informed2_pnl, overall_average_Informed3_pnl, overall_average_Informed4_pnl, overall_average_Informed5_pnl, overall_average_Informed6_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed1_pnl, overall_average_Informed2_pnl, overall_average_Informed3_pnl, overall_average_Informed4_pnl, overall_average_Informed5_pnl, overall_average_Informed6_pnl))))
lines(overall_average_Informed1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_Informed2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_Informed3_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Informed4_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Informed5_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Informed6_pnl, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed 1", "Informed 2", "Informed 3", "Informed 4", "Informed 5", "Informed 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed5_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed6_pos <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 7])), ", ")

  Informed1_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 9])), ", ")
  
  Informed2_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 11])), ", ")
  
  Informed3_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 13])), ", ")
  
  Informed4_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 15])), ", ")
  
  Informed5_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 17])), ", ")
  
  Informed6_pos_set1 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_1[n, 19])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pos <- sapply(MM_pos_set1, function(x) as.numeric(x[i]))
    Informed1_pos <- sapply(Informed1_pos_set1, function(x) as.numeric(x[i]))
    Informed2_pos <- sapply(Informed2_pos_set1, function(x) as.numeric(x[i]))
    Informed3_pos <- sapply(Informed3_pos_set1, function(x) as.numeric(x[i]))
    Informed4_pos <- sapply(Informed4_pos_set1, function(x) as.numeric(x[i]))
    Informed5_pos <- sapply(Informed5_pos_set1, function(x) as.numeric(x[i]))
    Informed6_pos <- sapply(Informed6_pos_set1, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
    average_Informed1_pos[i, n] <- mean(Informed1_pos, na.rm = TRUE)
    average_Informed2_pos[i, n] <- mean(Informed2_pos, na.rm = TRUE)
    average_Informed3_pos[i, n] <- mean(Informed3_pos, na.rm = TRUE)
    average_Informed4_pos[i, n] <- mean(Informed4_pos, na.rm = TRUE)
    average_Informed5_pos[i, n] <- mean(Informed5_pos, na.rm = TRUE)
    average_Informed6_pos[i, n] <- mean(Informed6_pos, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed1_pos <- rowMeans(average_Informed1_pos, na.rm = TRUE)
overall_average_Informed2_pos <- rowMeans(average_Informed2_pos, na.rm = TRUE)
overall_average_Informed3_pos <- rowMeans(average_Informed3_pos, na.rm = TRUE)
overall_average_Informed4_pos <- rowMeans(average_Informed4_pos, na.rm = TRUE)
overall_average_Informed5_pos <- rowMeans(average_Informed5_pos, na.rm = TRUE)
overall_average_Informed6_pos <- rowMeans(average_Informed6_pos, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed1_pos, overall_average_Informed2_pos, overall_average_Informed3_pos, overall_average_Informed4_pos, overall_average_Informed5_pos, overall_average_Informed6_pos)), max(c(overall_average_MM_pos, overall_average_Informed1_pos, overall_average_Informed2_pos, overall_average_Informed3_pos, overall_average_Informed4_pos, overall_average_Informed5_pos, overall_average_Informed6_pos))))
lines(overall_average_Informed1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_Informed2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_Informed3_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Informed4_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Informed5_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Informed6_pos, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed 1", "Informed 2", "Informed 3", "Informed 4", "Informed 5", "Informed 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set 2 (1 Informed + 1 noisy informed + 1 noisy + 1 stochastic noisy + 1 mr + 1 mom)

# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  TrueValues_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 2])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  ExpectedValues_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 3])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    True_values <- sapply(TrueValues_set1, function(x) as.numeric(x[i]))
    Expected_values <- sapply(ExpectedValues_set1, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_true[i, n] <- mean(True_values, na.rm = TRUE)
    average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  Bids_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 4])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  Asks_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 5])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    Bids <- sapply(Bids_set2, function(x) as.numeric(x[i]))
    Asks <- sapply(Asks_set2, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_bid[i, n] <- mean(Bids, na.rm = TRUE)
    average_ask[i, n] <- mean(Asks, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mr_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mom_pnl <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 6])), ", ")

  Informed_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 8])), ", ")
  
  NoisyInformed_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 10])), ", ")
  
  Noisy_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 12])), ", ")
  
  StochNoisy_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 14])), ", ")
  
  mr_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 16])), ", ")
  
  mom_pnl_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 18])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pnl <- sapply(MM_pnl_set2, function(x) as.numeric(x[i]))
    Informed_pnl <- sapply(Informed_pnl_set2, function(x) as.numeric(x[i]))
    NoisyInformed_pnl <- sapply(NoisyInformed_pnl_set2, function(x) as.numeric(x[i]))
    Noisy_pnl <- sapply(Noisy_pnl_set2, function(x) as.numeric(x[i]))
    StochNoisy_pnl <- sapply(StochNoisy_pnl_set2, function(x) as.numeric(x[i]))
    mr_pnl <- sapply(mr_pnl_set2, function(x) as.numeric(x[i]))
    mom_pnl <- sapply(mom_pnl_set2, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
    average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
    average_NoisyInformed_pnl[i, n] <- mean(NoisyInformed_pnl, na.rm = TRUE)
    average_Noisy_pnl[i, n] <- mean(Noisy_pnl, na.rm = TRUE)
    average_StochNoisy_pnl[i, n] <- mean(StochNoisy_pnl, na.rm = TRUE)
    average_mr_pnl[i, n] <- mean(mr_pnl, na.rm = TRUE)
    average_mom_pnl[i, n] <- mean(mom_pnl, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed_pnl <- rowMeans(average_NoisyInformed_pnl, na.rm = TRUE)
overall_average_Noisy_pnl <- rowMeans(average_Noisy_pnl, na.rm = TRUE)
overall_average_StochNoisy_pnl <- rowMeans(average_StochNoisy_pnl, na.rm = TRUE)
overall_average_mr_pnl <- rowMeans(average_mr_pnl, na.rm = TRUE)
overall_average_mom_pnl <- rowMeans(average_mom_pnl, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed_pnl, overall_average_Noisy_pnl, overall_average_StochNoisy_pnl, overall_average_mr_pnl, overall_average_mom_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed_pnl, overall_average_Noisy_pnl, overall_average_StochNoisy_pnl, overall_average_mr_pnl, overall_average_mom_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_StochNoisy_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_mr_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_mom_pnl, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed", "Noisy", "Stochastic Noisy", "Mean Reversion", "Momentum"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mr_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mom_pos <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 7])), ", ")

  Informed_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 9])), ", ")
  
  NoisyInformed_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 11])), ", ")
  
  Noisy_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 13])), ", ")
  
  StochNoisy_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 15])), ", ")
  
  mr_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 17])), ", ")
  
  mom_pos_set2 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_2[n, 19])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pos <- sapply(MM_pos_set2, function(x) as.numeric(x[i]))
    Informed_pos <- sapply(Informed_pos_set2, function(x) as.numeric(x[i]))
    NoisyInformed_pos <- sapply(NoisyInformed_pos_set2, function(x) as.numeric(x[i]))
    Noisy_pos <- sapply(Noisy_pos_set2, function(x) as.numeric(x[i]))
    StochNoisy_pos <- sapply(StochNoisy_pos_set2, function(x) as.numeric(x[i]))
    mr_pos <- sapply(mr_pos_set2, function(x) as.numeric(x[i]))
    mom_pos <- sapply(mom_pos_set2, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
    average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
    average_NoisyInformed_pos[i, n] <- mean(NoisyInformed_pos, na.rm = TRUE)
    average_Noisy_pos[i, n] <- mean(Noisy_pos, na.rm = TRUE)
    average_StochNoisy_pos[i, n] <- mean(StochNoisy_pos, na.rm = TRUE)
    average_mr_pos[i, n] <- mean(mr_pos, na.rm = TRUE)
    average_mom_pos[i, n] <- mean(mom_pos, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed_pos <- rowMeans(average_NoisyInformed_pos, na.rm = TRUE)
overall_average_Noisy_pos <- rowMeans(average_Noisy_pos, na.rm = TRUE)
overall_average_StochNoisy_pos <- rowMeans(average_StochNoisy_pos, na.rm = TRUE)
overall_average_mr_pos <- rowMeans(average_mr_pos, na.rm = TRUE)
overall_average_mom_pos <- rowMeans(average_mom_pos, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed_pos, overall_average_Noisy_pos, overall_average_StochNoisy_pos, overall_average_mr_pos, overall_average_mom_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed_pos, overall_average_Noisy_pos, overall_average_StochNoisy_pos, overall_average_mr_pos, overall_average_mom_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed_pos, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_StochNoisy_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_mr_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_mom_pos, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed", "Noisy", "Stochastic Noisy", "Mean Reversion", "Momentum"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set 3 (2 stochastic noisy + 2 mr + 2 mom)

# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  TrueValues_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 2])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  ExpectedValues_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 3])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    True_values <- sapply(TrueValues_set3, function(x) as.numeric(x[i]))
    Expected_values <- sapply(ExpectedValues_set3, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_true[i, n] <- mean(True_values, na.rm = TRUE)
    average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  Bids_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 4])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  Asks_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 5])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    Bids <- sapply(Bids_set3, function(x) as.numeric(x[i]))
    Asks <- sapply(Asks_set3, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_bid[i, n] <- mean(Bids, na.rm = TRUE)
    average_ask[i, n] <- mean(Asks, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mr1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mr2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mom1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_mom2_pnl <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 6])), ", ")

  StochNoisy1_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 8])), ", ")
  
  StochNoisy2_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 10])), ", ")
  
  mr1_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 12])), ", ")
  
  mr2_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 14])), ", ")
  
  mom1_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 16])), ", ")
  
  mom2_pnl_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 18])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pnl <- sapply(MM_pnl_set3, function(x) as.numeric(x[i]))
    StochNoisy1_pnl <- sapply(StochNoisy1_pnl_set3, function(x) as.numeric(x[i]))
    StochNoisy2_pnl <- sapply(StochNoisy2_pnl_set3, function(x) as.numeric(x[i]))
    mr1_pnl <- sapply(mr1_pnl_set3, function(x) as.numeric(x[i]))
    mr2_pnl <- sapply(mr2_pnl_set3, function(x) as.numeric(x[i]))
    mom1_pnl <- sapply(mom1_pnl_set3, function(x) as.numeric(x[i]))
    mom2_pnl <- sapply(mom2_pnl_set3, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
    average_StochNoisy1_pnl[i, n] <- mean(StochNoisy1_pnl, na.rm = TRUE)
    average_StochNoisy2_pnl[i, n] <- mean(StochNoisy2_pnl, na.rm = TRUE)
    average_mr1_pnl[i, n] <- mean(mr1_pnl, na.rm = TRUE)
    average_mr2_pnl[i, n] <- mean(mr2_pnl, na.rm = TRUE)
    average_mom1_pnl[i, n] <- mean(mom1_pnl, na.rm = TRUE)
    average_mom2_pnl[i, n] <- mean(mom2_pnl, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_StochNoisy1_pnl <- rowMeans(average_StochNoisy1_pnl, na.rm = TRUE)
overall_average_StochNoisy2_pnl <- rowMeans(average_StochNoisy2_pnl, na.rm = TRUE)
overall_average_mr1_pnl <- rowMeans(average_mr1_pnl, na.rm = TRUE)
overall_average_mr2_pnl <- rowMeans(average_mr2_pnl, na.rm = TRUE)
overall_average_mom1_pnl <- rowMeans(average_mom1_pnl, na.rm = TRUE)
overall_average_mom2_pnl <- rowMeans(average_mom2_pnl, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_StochNoisy1_pnl, overall_average_StochNoisy2_pnl, overall_average_mr1_pnl, overall_average_mr2_pnl, overall_average_mom1_pnl, overall_average_mom2_pnl)), max(c(overall_average_MM_pnl, overall_average_StochNoisy1_pnl, overall_average_StochNoisy2_pnl, overall_average_mr1_pnl, overall_average_mr2_pnl, overall_average_mom1_pnl, overall_average_mom2_pnl))))
lines(overall_average_StochNoisy1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_StochNoisy2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_mr1_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_mr2_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_mom1_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_mom2_pnl, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Stochastic Noisy 1", "Stochastic Noisy 2", "Mean Reversion 1", "Mean Reversion 2", "Momentum 1", "Momentum 2"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mr1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mr2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mom1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_mom2_pos <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 7])), ", ")

  StochNoisy1_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 9])), ", ")
  
  StochNoisy2_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 11])), ", ")
  
  mr1_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 12])), ", ")
  
  mr2_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 15])), ", ")
  
  mom1_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 17])), ", ")
  
  mom2_pos_set3 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_3[n, 19])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pos <- sapply(MM_pos_set3, function(x) as.numeric(x[i]))
    StochNoisy1_pos <- sapply(StochNoisy1_pos_set3, function(x) as.numeric(x[i]))
    StochNoisy2_pos <- sapply(StochNoisy2_pos_set3, function(x) as.numeric(x[i]))
    mr1_pos <- sapply(mr1_pos_set3, function(x) as.numeric(x[i]))
    mr2_pos <- sapply(mr2_pos_set3, function(x) as.numeric(x[i]))
    mom1_pos <- sapply(mom1_pos_set3, function(x) as.numeric(x[i]))
    mom2_pos <- sapply(mom2_pos_set3, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
    average_StochNoisy1_pos[i, n] <- mean(StochNoisy1_pos, na.rm = TRUE)
    average_StochNoisy2_pos[i, n] <- mean(StochNoisy2_pos, na.rm = TRUE)
    average_mr1_pos[i, n] <- mean(mr1_pos, na.rm = TRUE)
    average_mr2_pos[i, n] <- mean(mr2_pos, na.rm = TRUE)
    average_mom1_pos[i, n] <- mean(mom1_pos, na.rm = TRUE)
    average_mom2_pos[i, n] <- mean(mom2_pos, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_StochNoisy1_pos <- rowMeans(average_StochNoisy1_pos, na.rm = TRUE)
overall_average_StochNoisy2_pos <- rowMeans(average_StochNoisy2_pos, na.rm = TRUE)
overall_average_mr1_pos <- rowMeans(average_mr1_pos, na.rm = TRUE)
overall_average_mr2_pos <- rowMeans(average_mr2_pos, na.rm = TRUE)
overall_average_mom1_pos <- rowMeans(average_mom1_pos, na.rm = TRUE)
overall_average_mom2_pos <- rowMeans(average_mom2_pos, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_StochNoisy1_pos, overall_average_StochNoisy2_pos, overall_average_mr1_pos, overall_average_mr2_pos, overall_average_mom1_pos, overall_average_mom2_pos)), max(c(overall_average_MM_pos, overall_average_StochNoisy1_pos, overall_average_StochNoisy2_pos, overall_average_mr1_pos, overall_average_mr2_pos, overall_average_mom1_pos, overall_average_mom2_pos))))
lines(overall_average_StochNoisy1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_StochNoisy2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_mr1_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_mr2_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_mom1_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_mom2_pos, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Stochastic Noisy 1", "Stochastic Noisy 2", "Mean Reversion 1", "Mean Reversion 2", "Momentum 1", "Momentum 2"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set 4 (1 informed + 2 noisy informed + 2 noisy + 1 stochastic noisy)

# Initialize empty vectors to store true and expected values
TrueValues_set4 <- numeric()
ExpectedValues_set4 <- numeric()

# Loop through each iteration (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_1 dataframe
  TrueValue_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 2])), ", ")[[1]]
  
  # Extract Expected values from the aggregated_results_1 dataframe
  ExpectedValue_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 3])), ", ")[[1]]
  
  # Append the True and Expected values to their respective vectors
  TrueValues_set4 <- c(TrueValues_set4, as.numeric(TrueValue_set4))
  ExpectedValues_set4 <- c(ExpectedValues_set4, as.numeric(ExpectedValue_set4))
}

# Calculate the average of True values
average_true <- mean(TrueValues_set4)

# Calculate the average of Expected values
average_expected <- mean(ExpectedValues_set4)

# Plot True and Expected values on the same plot
plot(TrueValues_set4, type = "l", pch = 16, col = "blue", main = "True vs Expected Values in set 4", xlab = "Iteration", ylab = "Value")
lines(ExpectedValues_set4, type = "l", pch = 16, col = "red")

# Add legend
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Add horizontal lines for the averages
abline(h = average_true, col = "blue", lwd = 1)
abline(h = average_expected, col = "red", lwd = 1)

# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  TrueValues_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 2])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  ExpectedValues_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 3])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    True_values <- sapply(TrueValues_set4, function(x) as.numeric(x[i]))
    Expected_values <- sapply(ExpectedValues_set4, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_true[i, n] <- mean(True_values, na.rm = TRUE)
    average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize empty vectors to store the Bid and Ask values
Bids_set4 <- numeric()
Asks_set4 <- numeric()

# Loop through each iteration (n)
for (n in 1:10) {
  # Extract Bid values from the aggregated_results_1 dataframe
  Bid_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 4])), ", ")[[1]]
  
  # Extract Ask values from the aggregated_results_1 dataframe (next column)
  Ask_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 5])), ", ")[[1]]
  
  # Append the Bid and Ask values to their respective vectors
  Bids_set4 <- c(Bids_set4, as.numeric(Bid_set4))
  Asks_set4 <- c(Asks_set4, as.numeric(Ask_set4))
}

# Calculate the average of Bid and Ask values
average_bids <- mean(Bids_set4, na.rm = TRUE)
average_asks <- mean(Asks_set4, na.rm = TRUE)

# Plot the Bid and Ask values on the same plot
plot(Bids_set4, type = "l", pch = 16, col = "blue", main = "Bids vs Asks in set 4", xlab = "Iteration", ylab = "Value", ylim = c(min(c(Bids_set4, Asks_set4)), max(c(Bids_set4, Asks_set4))))
lines(Asks_set4, type = "l", pch = 16, col = "red")

# Add legend
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Add horizontal lines for the averages
abline(h = average_bids, col = "blue", lty = 1)
abline(h = average_asks, col = "red", lty = 1)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  Bids_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 4])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  Asks_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 5])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    Bids <- sapply(Bids_set4, function(x) as.numeric(x[i]))
    Asks <- sapply(Asks_set4, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_bid[i, n] <- mean(Bids, na.rm = TRUE)
    average_ask[i, n] <- mean(Asks, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize empty vectors to store the Bid and Ask values
MM_pnl_set4 <- numeric()
Informed_pnl_set4 <- numeric()
NoisyInformed1_pnl_set4 <- numeric()
NoisyInformed2_pnl_set4 <- numeric()
Noisy1_pnl_set4 <- numeric()
Noisy2_pnl_set4 <- numeric()
StochNoisy_pnl_set4 <- numeric()

# Loop through each iteration (n)
for (n in 1:10) {

  MM_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 6])), ", ")[[1]]
  
  Informed_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 8])), ", ")[[1]]
  
  NoisyInformed1_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 10])), ", ")[[1]]
  
  NoisyInformed2_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 12])), ", ")[[1]]
  
  Noisy1_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 14])), ", ")[[1]]
  
  Noisy2_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 16])), ", ")[[1]]
  
  StochNoisy_pnl_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 18])), ", ")[[1]]
  
  # Convert Bid and Ask values to numeric and append to the vectors
  MM_pnl_set4 <- c(MM_pnl_set4, as.numeric(MM_pnl_values))
  Informed_pnl_set4 <- c(Informed_pnl_set4, as.numeric(Informed_pnl_values))
  NoisyInformed1_pnl_set4 <- c(NoisyInformed1_pnl_set4, as.numeric(NoisyInformed1_pnl_values))
  NoisyInformed2_pnl_set4 <- c(NoisyInformed2_pnl_set4, as.numeric(NoisyInformed2_pnl_values))
  Noisy1_pnl_set4 <- c(Noisy_pnl_set4, as.numeric(Noisy1_pnl_values))
  Noisy2_pnl_set4 <- c(Noisy2_pnl_set4, as.numeric(Noisy2_pnl_values))
  StochNoisy_pnl_set4 <- c(StochNoisy_pnl_set4, as.numeric(StochNoisy_pnl_values))
}

# Calculate the average of Bid and Ask values
#average_MM <- mean(MM_set4, na.rm = TRUE)
#average_IN <- mean(IN_set4, na.rm = TRUE)

# Plot the Bid and Ask values on the same plot
plot(MM_pnl_set4, type = "l", pch = 16, col = "black", main = "PNL in set 4", xlab = "Iteration", ylab = "Value", ylim = c(min(c(MM_pnl_set4, Informed_pnl_set4, NoisyInformed1_pnl_set4, NoisyInformed2_pnl_set4, Noisy1_pnl_set4, Noisy2_pnl_set4, StochNoisy_pnl_set4)), max(c(MM_pnl_set4, Informed_pnl_set4, NoisyInformed1_pnl_set4, NoisyInformed2_pnl_set4, Noisy1_pnl_set4, Noisy2_pnl_set4, StochNoisy_pnl_set4))))
lines(Informed_pnl_set4, type = "l", pch = 16, col = "red")
lines(NoisyInformed1_pnl_set4, type = "l", pch = 16, col = "green")
lines(NoisyInformed2_pnl_set4, type = "l", pch = 16, col = "yellow")
lines(Noisy1_pnl_set4, type = "l", pch = 16, col = "blue")
lines(Noisy2_pnl_set4, type = "l", pch = 16, col = "purple")
lines(StochNoisy_pnl_set4, type = "l", pch = 16, col = "orange")


# Add legend
legend("bottomright", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Stochastic Noisy"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)


# Add horizontal lines for the averages
#abline(h = average_MM, col = "blue", lty = 1)
#abline(h = average_IN, col = "red", lty = 1)
# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy_pnl <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 6])), ", ")

  Informed_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 8])), ", ")
  
  NoisyInformed1_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 10])), ", ")
  
  NoisyInformed2_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 12])), ", ")
  
  Noisy1_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 14])), ", ")
  
  Noisy2_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 16])), ", ")
  
  StochNoisy_pnl_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 18])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pnl <- sapply(MM_pnl_set4, function(x) as.numeric(x[i]))
    Informed_pnl <- sapply(Informed_pnl_set4, function(x) as.numeric(x[i]))
    NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set4, function(x) as.numeric(x[i]))
    NoisyInformed2_pnl <- sapply(NoisyInformed2_pnl_set4, function(x) as.numeric(x[i]))
    Noisy1_pnl <- sapply(Noisy1_pnl_set4, function(x) as.numeric(x[i]))
    Noisy2_pnl <- sapply(Noisy2_pnl_set4, function(x) as.numeric(x[i]))
    StochNoisy_pnl <- sapply(StochNoisy_pnl_set4, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
    average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
    average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
    average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
    average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
    average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
    average_StochNoisy_pnl[i, n] <- mean(StochNoisy_pnl, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_StochNoisy_pnl <- rowMeans(average_StochNoisy_pnl, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_StochNoisy_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_StochNoisy_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_StochNoisy_pnl, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Stochastic Noisy"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize empty vectors to store the Bid and Ask values
MM_pos_set4 <- numeric()
Informed_pos_set4 <- numeric()
NoisyInformed1_pos_set4 <- numeric()
NoisyInformed2_pos_set4 <- numeric()
Noisy1_pos_set4 <- numeric()
Noisy2_pos_set4 <- numeric()
StochNoisy_pos_set4 <- numeric()

# Loop through each iteration (n)
for (n in 1:10) {

  MM_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 7])), ", ")[[1]]
  
  Informed_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 9])), ", ")[[1]]
  
  NoisyInformed1_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 11])), ", ")[[1]]
  
  NoisyInformed2_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 13])), ", ")[[1]]
  
  Noisy1_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 15])), ", ")[[1]]
  
  Noisy2_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 17])), ", ")[[1]]
  
  StochNoisy_pos_values <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 19])), ", ")[[1]]
  
  # Convert Bid and Ask values to numeric and append to the vectors
  MM_pos_set4 <- c(MM_pos_set4, as.numeric(MM_pos_values))
  Informed_pos_set4 <- c(Informed_pos_set4, as.numeric(Informed_pos_values))
  NoisyInformed1_pos_set4 <- c(NoisyInformed1_pos_set4, as.numeric(NoisyInformed1_pos_values))
  NoisyInformed2_pos_set4 <- c(NoisyInformed2_pos_set4, as.numeric(NoisyInformed2_pos_values))
  Noisy1_pos_set4 <- c(Noisy_pos_set4, as.numeric(Noisy1_pos_values))
  Noisy2_pos_set4 <- c(Noisy2_pos_set4, as.numeric(Noisy2_pos_values))
  StochNoisy_pos_set4 <- c(StochNoisy_pos_set4, as.numeric(StochNoisy_pos_values))
}

# Calculate the average of Bid and Ask values
#average_MM <- mean(MM_set4, na.rm = TRUE)
#average_IN <- mean(IN_set4, na.rm = TRUE)

# Plot the Bid and Ask values on the same plot
plot(MM_pos_set4, type = "l", pch = 16, col = "black", main = "Position in set 4", xlab = "Iteration", ylab = "Value", ylim = c(min(c(MM_pos_set4, Informed_pos_set4, NoisyInformed1_pos_set4, NoisyInformed2_pos_set4, Noisy1_pos_set4, Noisy2_pos_set4, StochNoisy_pos_set4)), max(c(MM_pos_set4, Informed_pos_set4, NoisyInformed1_pos_set4, NoisyInformed2_pos_set4, Noisy1_pos_set4, Noisy2_pos_set4, StochNoisy_pos_set4))))
lines(Informed_pos_set4, type = "l", pch = 16, col = "red")
lines(NoisyInformed1_pos_set4, type = "l", pch = 16, col = "green")
lines(NoisyInformed2_pos_set4, type = "l", pch = 16, col = "yellow")
lines(Noisy1_pos_set4, type = "l", pch = 16, col = "blue")
lines(Noisy2_pos_set4, type = "l", pch = 16, col = "purple")
lines(StochNoisy_pos_set4, type = "l", pch = 16, col = "orange")


# Add legend
legend("topleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Stochastic Noisy"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)


# Add horizontal lines for the averages
#abline(h = average_MM, col = "blue", lty = 1)
#abline(h = average_IN, col = "red", lty = 1)
# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_StochNoisy_pos <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 7])), ", ")

  Informed_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 9])), ", ")
  
  NoisyInformed1_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 11])), ", ")
  
  NoisyInformed2_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 13])), ", ")
  
  Noisy1_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 15])), ", ")
  
  Noisy2_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 17])), ", ")
  
  StochNoisy_pos_set4 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 19])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pos <- sapply(MM_pos_set4, function(x) as.numeric(x[i]))
    Informed_pos <- sapply(Informed_pos_set4, function(x) as.numeric(x[i]))
    NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set4, function(x) as.numeric(x[i]))
    NoisyInformed2_pos <- sapply(NoisyInformed2_pos_set4, function(x) as.numeric(x[i]))
    Noisy1_pos <- sapply(Noisy1_pos_set4, function(x) as.numeric(x[i]))
    Noisy2_pos <- sapply(Noisy2_pos_set4, function(x) as.numeric(x[i]))
    StochNoisy_pos <- sapply(StochNoisy_pos_set4, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
    average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
    average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
    average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
    average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
    average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
    average_StochNoisy_pos[i, n] <- mean(StochNoisy_pos, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_StochNoisy_pos <- rowMeans(average_StochNoisy_pos, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_StochNoisy_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_StochNoisy_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_StochNoisy_pos, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 1", "Noisy 2", "Stochastic Noisy"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set 5 (Noisy*6)

# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  TrueValues_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 2])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  ExpectedValues_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_4[n, 3])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    True_values <- sapply(TrueValues_set5, function(x) as.numeric(x[i]))
    Expected_values <- sapply(ExpectedValues_set5, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_true[i, n] <- mean(True_values, na.rm = TRUE)
    average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  Bids_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 4])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  Asks_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 5])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    Bids <- sapply(Bids_set5, function(x) as.numeric(x[i]))
    Asks <- sapply(Asks_set5, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_bid[i, n] <- mean(Bids, na.rm = TRUE)
    average_ask[i, n] <- mean(Asks, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy5_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy6_pnl <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 6])), ", ")

  Noisy1_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 8])), ", ")
  
  Noisy2_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 10])), ", ")
  
  Noisy3_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 12])), ", ")
  
  Noisy4_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 14])), ", ")
  
  Noisy5_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 16])), ", ")
  
  Noisy6_pnl_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 18])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pnl <- sapply(MM_pnl_set5, function(x) as.numeric(x[i]))
    Noisy1_pnl <- sapply(Noisy1_pnl_set5, function(x) as.numeric(x[i]))
    Noisy2_pnl <- sapply(Noisy2_pnl_set5, function(x) as.numeric(x[i]))
    Noisy3_pnl <- sapply(Noisy3_pnl_set5, function(x) as.numeric(x[i]))
    Noisy4_pnl <- sapply(Noisy4_pnl_set5, function(x) as.numeric(x[i]))
    Noisy5_pnl <- sapply(Noisy5_pnl_set5, function(x) as.numeric(x[i]))
    Noisy6_pnl <- sapply(Noisy6_pnl_set5, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
    average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
    average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
    average_Noisy3_pnl[i, n] <- mean(Noisy3_pnl, na.rm = TRUE)
    average_Noisy4_pnl[i, n] <- mean(Noisy4_pnl, na.rm = TRUE)
    average_Noisy5_pnl[i, n] <- mean(Noisy5_pnl, na.rm = TRUE)
    average_Noisy6_pnl[i, n] <- mean(Noisy6_pnl, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_Noisy3_pnl <- rowMeans(average_Noisy3_pnl, na.rm = TRUE)
overall_average_Noisy4_pnl <- rowMeans(average_Noisy4_pnl, na.rm = TRUE)
overall_average_Noisy5_pnl <- rowMeans(average_Noisy5_pnl, na.rm = TRUE)
overall_average_Noisy6_pnl <- rowMeans(average_Noisy6_pnl, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl, overall_average_Noisy4_pnl, overall_average_Noisy5_pnl, overall_average_Noisy6_pnl)), max(c(overall_average_MM_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl, overall_average_Noisy4_pnl, overall_average_Noisy5_pnl, overall_average_Noisy6_pnl))))
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy3_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy4_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy5_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy6_pnl, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Noisy 1", "Noisy 2", "Noisy 3", "Noisy 4", "Noisy 5", "Noisy 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy5_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy6_pos <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 7])), ", ")

  Noisy1_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 9])), ", ")
  
  Noisy2_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 11])), ", ")
  
  Noisy3_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 13])), ", ")
  
  Noisy4_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 15])), ", ")
  
  Noisy5_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 17])), ", ")
  
  Noisy6_pos_set5 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_5[n, 19])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pos <- sapply(MM_pos_set5, function(x) as.numeric(x[i]))
    Noisy1_pos <- sapply(Noisy1_pos_set5, function(x) as.numeric(x[i]))
    Noisy2_pos <- sapply(Noisy2_pos_set5, function(x) as.numeric(x[i]))
    Noisy3_pos <- sapply(Noisy3_pos_set5, function(x) as.numeric(x[i]))
    Noisy4_pos <- sapply(Noisy4_pos_set5, function(x) as.numeric(x[i]))
    Noisy5_pos <- sapply(Noisy5_pos_set5, function(x) as.numeric(x[i]))
    Noisy6_pos <- sapply(Noisy6_pos_set5, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
    average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
    average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
    average_Noisy3_pos[i, n] <- mean(Noisy3_pos, na.rm = TRUE)
    average_Noisy4_pos[i, n] <- mean(Noisy4_pos, na.rm = TRUE)
    average_Noisy5_pos[i, n] <- mean(Noisy5_pos, na.rm = TRUE)
    average_Noisy6_pos[i, n] <- mean(Noisy6_pos, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_Noisy3_pos <- rowMeans(average_Noisy3_pos, na.rm = TRUE)
overall_average_Noisy4_pos <- rowMeans(average_Noisy4_pos, na.rm = TRUE)
overall_average_Noisy5_pos <- rowMeans(average_Noisy5_pos, na.rm = TRUE)
overall_average_Noisy6_pos <- rowMeans(average_Noisy6_pos, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos, overall_average_Noisy4_pos, overall_average_Noisy5_pos, overall_average_Noisy6_pos)), max(c(overall_average_MM_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos, overall_average_Noisy4_pos, overall_average_Noisy5_pos, overall_average_Noisy6_pos))))
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "red")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy3_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy4_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy5_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy6_pos, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomright", legend = c("Market Maker", "Noisy 1", "Noisy 2", "Noisy 3", "Noisy 4", "Noisy 5", "Noisy 6"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set6 (1 informed + 5 noisy)

# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  TrueValues_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 2])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  ExpectedValues_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 3])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    True_values <- sapply(TrueValues_set6, function(x) as.numeric(x[i]))
    Expected_values <- sapply(ExpectedValues_set6, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_true[i, n] <- mean(True_values, na.rm = TRUE)
    average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  Bids_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 4])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  Asks_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 5])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    Bids <- sapply(Bids_set6, function(x) as.numeric(x[i]))
    Asks <- sapply(Asks_set6, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_bid[i, n] <- mean(Bids, na.rm = TRUE)
    average_ask[i, n] <- mean(Asks, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy5_pnl <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 6])), ", ")

  Informed_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 8])), ", ")
  
  Noisy1_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 10])), ", ")
  
  Noisy2_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 12])), ", ")
  
  Noisy3_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 14])), ", ")
  
  Noisy4_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 16])), ", ")
  
  Noisy5_pnl_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 18])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pnl <- sapply(MM_pnl_set6, function(x) as.numeric(x[i]))
    Informed_pnl <- sapply(Informed_pnl_set6, function(x) as.numeric(x[i]))
    Noisy1_pnl <- sapply(Noisy1_pnl_set6, function(x) as.numeric(x[i]))
    Noisy2_pnl <- sapply(Noisy2_pnl_set6, function(x) as.numeric(x[i]))
    Noisy3_pnl <- sapply(Noisy3_pnl_set6, function(x) as.numeric(x[i]))
    Noisy4_pnl <- sapply(Noisy4_pnl_set6, function(x) as.numeric(x[i]))
    Noisy5_pnl <- sapply(Noisy5_pnl_set6, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
    average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
    average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
    average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
    average_Noisy3_pnl[i, n] <- mean(Noisy3_pnl, na.rm = TRUE)
    average_Noisy4_pnl[i, n] <- mean(Noisy4_pnl, na.rm = TRUE)
    average_Noisy5_pnl[i, n] <- mean(Noisy5_pnl, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_Noisy3_pnl <- rowMeans(average_Noisy3_pnl, na.rm = TRUE)
overall_average_Noisy4_pnl <- rowMeans(average_Noisy4_pnl, na.rm = TRUE)
overall_average_Noisy5_pnl <- rowMeans(average_Noisy5_pnl, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl, overall_average_Noisy4_pnl, overall_average_Noisy5_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl, overall_average_Noisy4_pnl, overall_average_Noisy5_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy3_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy4_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy5_pnl, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy 1", "Noisy 2", "Noisy 3", "Noisy 4", "Noisy 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy5_pos <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 7])), ", ")

  Informed_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 9])), ", ")
  
  Noisy1_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 11])), ", ")
  
  Noisy2_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 13])), ", ")
  
  Noisy3_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 15])), ", ")
  
  Noisy4_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 17])), ", ")
  
  Noisy5_pos_set6 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_6[n, 19])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pos <- sapply(MM_pos_set6, function(x) as.numeric(x[i]))
    Informed_pos <- sapply(Informed_pnl_set6, function(x) as.numeric(x[i]))
    Noisy1_pos <- sapply(Noisy1_pos_set6, function(x) as.numeric(x[i]))
    Noisy2_pos <- sapply(Noisy2_pos_set6, function(x) as.numeric(x[i]))
    Noisy3_pos <- sapply(Noisy3_pos_set6, function(x) as.numeric(x[i]))
    Noisy4_pos <- sapply(Noisy4_pos_set6, function(x) as.numeric(x[i]))
    Noisy5_pos <- sapply(Noisy5_pos_set6, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
    average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
    average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
    average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
    average_Noisy3_pos[i, n] <- mean(Noisy3_pos, na.rm = TRUE)
    average_Noisy4_pos[i, n] <- mean(Noisy4_pos, na.rm = TRUE)
    average_Noisy5_pos[i, n] <- mean(Noisy5_pos, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_Noisy3_pos <- rowMeans(average_Noisy3_pos, na.rm = TRUE)
overall_average_Noisy4_pos <- rowMeans(average_Noisy4_pos, na.rm = TRUE)
overall_average_Noisy5_pos <- rowMeans(average_Noisy5_pos, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos, overall_average_Noisy4_pos, overall_average_Noisy5_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos, overall_average_Noisy4_pos, overall_average_Noisy5_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy3_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy4_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy5_pos, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy 1", "Noisy 2", "Noisy 3", "Noisy 4", "Noisy 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set7 (1 informed + 5 noisy informed)

# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  TrueValues_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 2])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  ExpectedValues_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 3])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    True_values <- sapply(TrueValues_set7, function(x) as.numeric(x[i]))
    Expected_values <- sapply(ExpectedValues_set6, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_true[i, n] <- mean(True_values, na.rm = TRUE)
    average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  Bids_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 4])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  Asks_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 5])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    Bids <- sapply(Bids_set7, function(x) as.numeric(x[i]))
    Asks <- sapply(Asks_set7, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_bid[i, n] <- mean(Bids, na.rm = TRUE)
    average_ask[i, n] <- mean(Asks, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed3_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed4_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed5_pnl <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 6])), ", ")

  Informed_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 8])), ", ")
  
  NoisyInformed1_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 10])), ", ")
  
  NoisyInformed2_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 12])), ", ")
  
  NoisyInformed3_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 14])), ", ")
  
  NoisyInformed4_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 16])), ", ")
  
  NoisyInformed5_pnl_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 18])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pnl <- sapply(MM_pnl_set7, function(x) as.numeric(x[i]))
    Informed_pnl <- sapply(Informed_pnl_set7, function(x) as.numeric(x[i]))
    NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set7, function(x) as.numeric(x[i]))
    NoisyInformed2_pnl <- sapply(NoisyInformed2_pnl_set7, function(x) as.numeric(x[i]))
    NoisyInformed3_pnl <- sapply(NoisyInformed3_pnl_set7, function(x) as.numeric(x[i]))
    NoisyInformed4_pnl <- sapply(NoisyInformed4_pnl_set7, function(x) as.numeric(x[i]))
    NoisyInformed5_pnl <- sapply(NoisyInformed5_pnl_set7, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
    average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
    average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
    average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
    average_NoisyInformed3_pnl[i, n] <- mean(NoisyInformed3_pnl, na.rm = TRUE)
    average_NoisyInformed4_pnl[i, n] <- mean(NoisyInformed4_pnl, na.rm = TRUE)
    average_NoisyInformed5_pnl[i, n] <- mean(NoisyInformed5_pnl, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_NoisyInformed3_pnl <- rowMeans(average_NoisyInformed3_pnl, na.rm = TRUE)
overall_average_NoisyInformed4_pnl <- rowMeans(average_NoisyInformed4_pnl, na.rm = TRUE)
overall_average_NoisyInformed5_pnl <- rowMeans(average_NoisyInformed5_pnl, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_NoisyInformed3_pnl, overall_average_NoisyInformed4_pnl, overall_average_NoisyInformed5_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_NoisyInformed3_pnl, overall_average_NoisyInformed4_pnl, overall_average_NoisyInformed5_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_NoisyInformed3_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_NoisyInformed4_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_NoisyInformed5_pnl, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy Informed 3", "Noisy Informed 4", "Noisy Informed 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pos <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed3_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed4_pos <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed5_pos <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 7])), ", ")

  Informed_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 9])), ", ")
  
  NoisyInformed1_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 11])), ", ")
  
  NoisyInformed2_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 13])), ", ")
  
  NoisyInformed3_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 15])), ", ")
  
  NoisyInformed4_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 17])), ", ")
  
  NoisyInformed5_pos_set7 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_7[n, 19])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pos <- sapply(MM_pos_set7, function(x) as.numeric(x[i]))
    Informed_pos <- sapply(Informed_pos_set7, function(x) as.numeric(x[i]))
    NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set7, function(x) as.numeric(x[i]))
    NoisyInformed2_pos <- sapply(NoisyInformed2_pos_set7, function(x) as.numeric(x[i]))
    NoisyInformed3_pos <- sapply(NoisyInformed3_pos_set7, function(x) as.numeric(x[i]))
    NoisyInformed4_pos <- sapply(NoisyInformed4_pos_set7, function(x) as.numeric(x[i]))
    NoisyInformed5_pos <- sapply(NoisyInformed5_pos_set7, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
    average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
    average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
    average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
    average_NoisyInformed3_pos[i, n] <- mean(NoisyInformed3_pos, na.rm = TRUE)
    average_NoisyInformed4_pos[i, n] <- mean(NoisyInformed4_pos, na.rm = TRUE)
    average_NoisyInformed5_pos[i, n] <- mean(NoisyInformed5_pos, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_NoisyInformed3_pos <- rowMeans(average_NoisyInformed3_pos, na.rm = TRUE)
overall_average_NoisyInformed4_pos <- rowMeans(average_NoisyInformed4_pos, na.rm = TRUE)
overall_average_NoisyInformed5_pos <- rowMeans(average_NoisyInformed5_pos, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_NoisyInformed3_pos, overall_average_NoisyInformed4_pos, overall_average_NoisyInformed5_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_NoisyInformed3_pos, overall_average_NoisyInformed4_pos, overall_average_NoisyInformed5_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_NoisyInformed3_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_NoisyInformed4_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_NoisyInformed5_pos, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy Informed 3", "Noisy Informed 4", "Noisy Informed 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set8 (1 informed + 2 noisy informed + 3 noisy)

# Initialize matrices to store averages for each position
average_true <- matrix(NA, nrow = 100, ncol = 10)
average_expected <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  TrueValues_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 2])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  ExpectedValues_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 3])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    True_values <- sapply(TrueValues_set7, function(x) as.numeric(x[i]))
    Expected_values <- sapply(ExpectedValues_set6, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_true[i, n] <- mean(True_values, na.rm = TRUE)
    average_expected[i, n] <- mean(Expected_values, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_true <- rowMeans(average_true, na.rm = TRUE)
overall_average_expected <- rowMeans(average_expected, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_true, type = "l", pch = 16, col = "blue", main = "Overall Average of True vs Expected Values", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_true, overall_average_expected)), max(c(overall_average_true, overall_average_expected))))
lines(overall_average_expected, type = "l", pch = 16, col = "red")
legend("topright", legend = c("True Values", "Expected Values"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_bid <- matrix(NA, nrow = 100, ncol = 10)
average_ask <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {
  # Extract True values from the aggregated_results_4 dataframe
  Bids_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 4])), ", ")
  
  # Extract Expected values from the aggregated_results_4 dataframe
  Asks_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 5])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    Bids <- sapply(Bids_set8, function(x) as.numeric(x[i]))
    Asks <- sapply(Asks_set8, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_bid[i, n] <- mean(Bids, na.rm = TRUE)
    average_ask[i, n] <- mean(Asks, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_bid <- rowMeans(average_bid, na.rm = TRUE)
overall_average_ask <- rowMeans(average_ask, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_bid, type = "l", pch = 16, col = "blue", main = "Overall Average of Bids vs Asks", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_bid, overall_average_ask)), max(c(overall_average_bid, overall_average_ask))))
lines(overall_average_ask, type = "l", pch = 16, col = "red")
legend("topright", legend = c("Bids", "Asks"), col = c("blue", "red"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pnl <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 6])), ", ")

  Informed_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 8])), ", ")
  
  NoisyInformed1_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 10])), ", ")
  
  NoisyInformed2_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 12])), ", ")
  
  Noisy1_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 14])), ", ")
  
  Noisy2_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 16])), ", ")
  
  Noisy3_pnl_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 18])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pnl <- sapply(MM_pnl_set8, function(x) as.numeric(x[i]))
    Informed_pnl <- sapply(Informed_pnl_set8, function(x) as.numeric(x[i]))
    NoisyInformed1_pnl <- sapply(NoisyInformed1_pnl_set8, function(x) as.numeric(x[i]))
    NoisyInformed2_pnl <- sapply(NoisyInformed2_pnl_set8, function(x) as.numeric(x[i]))
    Noisy1_pnl <- sapply(Noisy1_pnl_set8, function(x) as.numeric(x[i]))
    Noisy2_pnl <- sapply(Noisy2_pnl_set8, function(x) as.numeric(x[i]))
    Noisy3_pnl <- sapply(Noisy3_pnl_set8, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pnl[i, n] <- mean(MM_pnl, na.rm = TRUE)
    average_Informed_pnl[i, n] <- mean(Informed_pnl, na.rm = TRUE)
    average_NoisyInformed1_pnl[i, n] <- mean(NoisyInformed1_pnl, na.rm = TRUE)
    average_NoisyInformed2_pnl[i, n] <- mean(NoisyInformed2_pnl, na.rm = TRUE)
    average_Noisy1_pnl[i, n] <- mean(Noisy1_pnl, na.rm = TRUE)
    average_Noisy2_pnl[i, n] <- mean(Noisy2_pnl, na.rm = TRUE)
    average_Noisy3_pnl[i, n] <- mean(Noisy3_pnl, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pnl <- rowMeans(average_MM_pnl, na.rm = TRUE)
overall_average_Informed_pnl <- rowMeans(average_Informed_pnl, na.rm = TRUE)
overall_average_NoisyInformed1_pnl <- rowMeans(average_NoisyInformed1_pnl, na.rm = TRUE)
overall_average_NoisyInformed2_pnl <- rowMeans(average_NoisyInformed2_pnl, na.rm = TRUE)
overall_average_Noisy1_pnl <- rowMeans(average_Noisy1_pnl, na.rm = TRUE)
overall_average_Noisy2_pnl <- rowMeans(average_Noisy2_pnl, na.rm = TRUE)
overall_average_Noisy3_pnl <- rowMeans(average_Noisy3_pnl, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pnl, type = "l", pch = 16, col = "black", main = "Overall Average PNL", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl)), max(c(overall_average_MM_pnl, overall_average_Informed_pnl, overall_average_NoisyInformed1_pnl, overall_average_NoisyInformed2_pnl, overall_average_Noisy1_pnl, overall_average_Noisy2_pnl, overall_average_Noisy3_pnl))))
lines(overall_average_Informed_pnl, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pnl, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pnl, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pnl, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pnl, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy3_pnl, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 3", "Noisy 4", "Noisy 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

# Initialize matrices to store averages for each position
average_MM_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Informed_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_NoisyInformed2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy1_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy2_pnl <- matrix(NA, nrow = 100, ncol = 10)
average_Noisy3_pnl <- matrix(NA, nrow = 100, ncol = 10)

# Loop through each simulation (n)
for (n in 1:10) {

  MM_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 7])), ", ")

  Informed_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 9])), ", ")
  
  NoisyInformed1_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 11])), ", ")
  
  NoisyInformed2_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 13])), ", ")
  
  Noisy1_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 15])), ", ")
  
  Noisy2_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 17])), ", ")
  
  Noisy3_pos_set8 <- strsplit(gsub("\\[|\\]", "", unlist(aggregated_results_8[n, 19])), ", ")
  
  # Loop through each position (i)
  for (i in 1:100) {
    # Extract True and Expected values for the i-th position
    MM_pos <- sapply(MM_pos_set8, function(x) as.numeric(x[i]))
    Informed_pos <- sapply(Informed_pos_set8, function(x) as.numeric(x[i]))
    NoisyInformed1_pos <- sapply(NoisyInformed1_pos_set8, function(x) as.numeric(x[i]))
    NoisyInformed2_pos <- sapply(NoisyInformed2_pos_set8, function(x) as.numeric(x[i]))
    Noisy1_pos <- sapply(Noisy1_pos_set8, function(x) as.numeric(x[i]))
    Noisy2_pos <- sapply(Noisy2_pos_set8, function(x) as.numeric(x[i]))
    Noisy3_pos <- sapply(Noisy3_pos_set8, function(x) as.numeric(x[i]))
    
    # Calculate the average of True and Expected values for the i-th position
    average_MM_pos[i, n] <- mean(MM_pos, na.rm = TRUE)
    average_Informed_pos[i, n] <- mean(Informed_pos, na.rm = TRUE)
    average_NoisyInformed1_pos[i, n] <- mean(NoisyInformed1_pos, na.rm = TRUE)
    average_NoisyInformed2_pos[i, n] <- mean(NoisyInformed2_pos, na.rm = TRUE)
    average_Noisy1_pos[i, n] <- mean(Noisy1_pos, na.rm = TRUE)
    average_Noisy2_pos[i, n] <- mean(Noisy2_pos, na.rm = TRUE)
    average_Noisy3_pos[i, n] <- mean(Noisy3_pos, na.rm = TRUE)
  }
}

# Calculate the overall average for each position across all simulations
overall_average_MM_pos <- rowMeans(average_MM_pos, na.rm = TRUE)
overall_average_Informed_pos <- rowMeans(average_Informed_pos, na.rm = TRUE)
overall_average_NoisyInformed1_pos <- rowMeans(average_NoisyInformed1_pos, na.rm = TRUE)
overall_average_NoisyInformed2_pos <- rowMeans(average_NoisyInformed2_pos, na.rm = TRUE)
overall_average_Noisy1_pos <- rowMeans(average_Noisy1_pos, na.rm = TRUE)
overall_average_Noisy2_pos <- rowMeans(average_Noisy2_pos, na.rm = TRUE)
overall_average_Noisy3_pos <- rowMeans(average_Noisy3_pos, na.rm = TRUE)

# Plot the overall averages
plot(overall_average_MM_pos, type = "l", pch = 16, col = "black", main = "Overall Average Position", xlab = "Position in List", ylab = "Value", ylim = c(min(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos)), max(c(overall_average_MM_pos, overall_average_Informed_pos, overall_average_NoisyInformed1_pos, overall_average_NoisyInformed2_pos, overall_average_Noisy1_pos, overall_average_Noisy2_pos, overall_average_Noisy3_pos))))
lines(overall_average_Informed_pos, type = "l", pch = 16, col = "red")
lines(overall_average_NoisyInformed1_pos, type = "l", pch = 16, col = "green")
lines(overall_average_NoisyInformed2_pos, type = "l", pch = 16, col = "yellow")
lines(overall_average_Noisy1_pos, type = "l", pch = 16, col = "blue")
lines(overall_average_Noisy2_pos, type = "l", pch = 16, col = "purple")
lines(overall_average_Noisy3_pos, type = "l", pch = 16, col = "orange")

# Add legend
legend("bottomleft", legend = c("Market Maker", "Informed", "Noisy Informed 1", "Noisy Informed 2", "Noisy 3", "Noisy 4", "Noisy 5"), col = c("black", "red", "green", "yellow", "blue", "purple", "orange"), lty = 1, cex = 0.8)

set9

set10

set11

set12

set13

set14

set15

LS0tCnRpdGxlOiAiRGF0YSBBbmFseXNpcyBhbmQgR2FtZSBUaGVvcnkiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoc3RhdHMpCmBgYAoKIyMjIFRydWUgdmFsdWUgaW4gc2V0MSwgc2ltMQoKYGBge3J9ClRydWVWYWx1ZV9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xWzEsIDJdKSksICIsICIpW1sxXV0KI2F2ZXJhZ2UgPC0gbWVhbihUcnVlVmFsdWVzX3NldDEpCnBsb3QoVHJ1ZVZhbHVlX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiVHJ1ZSBWYWx1ZXMgaW4gc2ltMCIsIHhsYWIgPSAiSXRlcmF0aW9uIiwgeWxhYiA9ICJWYWx1ZSIpCgojVHJ1ZVZhbHVlX3NldDFfc2ltMCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVsxLCAyXSkpLCAiLCAiKVtbMV1dCiN1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbMSwgMl0pCiNjbGVhbl9zdHIgPSBnc3ViKCJcXFt8XFxdIiwgIiIsIFRydWVWYWx1ZV9zaW0wKQojVHJ1ZVZhbHVlX3NldDFfc2ltMSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVsyLCAyXSkpLCAiLCAiKVtbMV1dCgojcHJpbnQoVmFsdWVzKQojWCA8LSAxOjEwMAojcGxvdChUcnVlVmFsdWVfc2V0MV9zaW0wLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIlRydWUgVmFsdWVzIGluIHNpbTAiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiKQojcGxvdChUcnVlVmFsdWVfc2V0MV9zaW0xLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIlRydWUgVmFsdWVzIGluIHNpbTEiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiKQoKI2ZpdCA8LSBsbShWYWx1ZXMgfiBYKQojYWJsaW5lKGZpdCwgY29sID0gInJlZCIpCmBgYAojIyMgVHJ1ZSB2YWx1ZXMgaW4gc2V0IDEsIGFsbCBzaW0KCmBgYHtyfQojIEluaXRpYWxpemUgYW4gZW1wdHkgdmVjdG9yIHRvIHN0b3JlIHRoZSBUcnVlIHZhbHVlcwpUcnVlVmFsdWVzX3NldDEgPC0gbnVtZXJpYygpCgojIExvb3AgdGhyb3VnaCBlYWNoIGl0ZXJhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzEgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgMl0pKSwgIiwgIilbWzFdXQogIAogICMgQXBwZW5kIHRoZSBUcnVlIHZhbHVlcyB0byB0aGUgdmVjdG9yCiAgVHJ1ZVZhbHVlc19zZXQxIDwtIGMoVHJ1ZVZhbHVlc19zZXQxLCBhcy5udW1lcmljKFRydWVWYWx1ZV9zZXQxKSkKfQoKIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSB2YWx1ZXMKYXZlcmFnZSA8LSBtZWFuKFRydWVWYWx1ZXNfc2V0MSkKCiMgUGxvdCB0aGUgYXZlcmFnZQpwbG90KFRydWVWYWx1ZXNfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJUcnVlIFZhbHVlcyBpbiBzZXQgMSIsIHhsYWIgPSAiSXRlcmF0aW9uIiwgeWxhYiA9ICJWYWx1ZSIpCgojIEFkZCBhIGhvcml6b250YWwgbGluZSBmb3IgdGhlIGF2ZXJhZ2UKYWJsaW5lKGggPSBhdmVyYWdlLCBjb2wgPSAicmVkIiwgbHdkID0gMikKCmBgYAoKIyMjIEV4cGVjdGVkIHZhbHVlIGluIHNldDEsIGFsbCBzaW0KCmBgYHtyfQojIEluaXRpYWxpemUgYW4gZW1wdHkgdmVjdG9yIHRvIHN0b3JlIHRoZSBUcnVlIHZhbHVlcwpFeHBlY3RlZFZhbHVlc19zZXQxIDwtIG51bWVyaWMoKQoKIyBMb29wIHRocm91Z2ggZWFjaCBpdGVyYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c18xIGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAzXSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBBcHBlbmQgdGhlIFRydWUgdmFsdWVzIHRvIHRoZSB2ZWN0b3IKICBFeHBlY3RlZFZhbHVlc19zZXQxIDwtIGMoRXhwZWN0ZWRWYWx1ZXNfc2V0MSwgYXMubnVtZXJpYyhFeHBlY3RlZFZhbHVlX3NldDEpKQp9CgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIHZhbHVlcwphdmVyYWdlIDwtIG1lYW4oRXhwZWN0ZWRWYWx1ZXNfc2V0MSkKCiMgUGxvdCB0aGUgYXZlcmFnZQpwbG90KEV4cGVjdGVkVmFsdWVzX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiRXhwZWN0ZWQgVmFsdWVzIGluIHNldCAxIiwgeGxhYiA9ICJJdGVyYXRpb24iLCB5bGFiID0gIlZhbHVlIikKCiMgQWRkIGEgaG9yaXpvbnRhbCBsaW5lIGZvciB0aGUgYXZlcmFnZQphYmxpbmUoaCA9IGF2ZXJhZ2UsIGNvbCA9ICJyZWQiLCBsd2QgPSAyKQoKYGBgCgojIyMgVHJ1ZSBhbmQgRXhwZWN0ZWQgVmFsdWVzIGluIHNldCAxCgpgYGB7cn0KIyBJbml0aWFsaXplIGVtcHR5IHZlY3RvcnMgdG8gc3RvcmUgdHJ1ZSBhbmQgZXhwZWN0ZWQgdmFsdWVzClRydWVWYWx1ZXNfc2V0MSA8LSBudW1lcmljKCkKRXhwZWN0ZWRWYWx1ZXNfc2V0MSA8LSBudW1lcmljKCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggaXRlcmF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUKICBUcnVlVmFsdWVfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAyXSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgM10pKSwgIiwgIilbWzFdXQogIAogICMgQXBwZW5kIHRoZSBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSB2ZWN0b3JzCiAgVHJ1ZVZhbHVlc19zZXQxIDwtIGMoVHJ1ZVZhbHVlc19zZXQxLCBhcy5udW1lcmljKFRydWVWYWx1ZV9zZXQxKSkKICBFeHBlY3RlZFZhbHVlc19zZXQxIDwtIGMoRXhwZWN0ZWRWYWx1ZXNfc2V0MSwgYXMubnVtZXJpYyhFeHBlY3RlZFZhbHVlX3NldDEpKQp9CgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIHZhbHVlcwphdmVyYWdlX3RydWUgPC0gbWVhbihUcnVlVmFsdWVzX3NldDEpCgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBFeHBlY3RlZCB2YWx1ZXMKYXZlcmFnZV9leHBlY3RlZCA8LSBtZWFuKEV4cGVjdGVkVmFsdWVzX3NldDEpCgojIFBsb3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIG9uIHRoZSBzYW1lIHBsb3QKcGxvdChUcnVlVmFsdWVzX3NldDEsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMgaW4gc2V0IDEiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiKQpsaW5lcyhFeHBlY3RlZFZhbHVlc19zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIEFkZCBob3Jpem9udGFsIGxpbmVzIGZvciB0aGUgYXZlcmFnZXMKYWJsaW5lKGggPSBhdmVyYWdlX3RydWUsIGNvbCA9ICJibHVlIiwgbHdkID0gMSkKYWJsaW5lKGggPSBhdmVyYWdlX2V4cGVjdGVkLCBjb2wgPSAicmVkIiwgbHdkID0gMSkKYGBgCgojIyMgQmlkcyBpbiBzZXQxLCBzaW0xCgoKYGBge3J9CkJpZHNfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVsxLCA0XSkpLCAiLCAiKVtbMV1dCiNhdmVyYWdlIDwtIG1lYW4oVHJ1ZVZhbHVlc19zZXQxKQpwbG90KEJpZHNfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJUcnVlIFZhbHVlcyBpbiBzaW0wIiwgeGxhYiA9ICJJdGVyYXRpb24iLCB5bGFiID0gIlZhbHVlIikKYGBgCgojIyMgQmlkcyBpbiBzZXQgMSwgYWxsIHNpbQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBhbiBlbXB0eSB2ZWN0b3IgdG8gc3RvcmUgdGhlIFRydWUgdmFsdWVzCkJpZHNfc2V0MSA8LSBudW1lcmljKCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggaXRlcmF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUKICBCaWRfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCA0XSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBBcHBlbmQgdGhlIFRydWUgdmFsdWVzIHRvIHRoZSB2ZWN0b3IgKGNvcnJlY3RlZCB0eXBvKQogIEJpZHNfc2V0MSA8LSBjKEJpZHNfc2V0MSwgYXMubnVtZXJpYyhCaWRfc2V0MSkpCn0KCiMgQ2hlY2sgaWYgdGhlIHZlY3RvciBpcyBwcm9wZXJseSBwb3B1bGF0ZWQKI3ByaW50KEJpZHNfc2V0MSkKCiMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgdmFsdWVzCmF2ZXJhZ2UgPC0gbWVhbihCaWRzX3NldDEsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgdmFsdWVzCnBsb3QoQmlkc19zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIkV4cGVjdGVkIFZhbHVlcyBpbiBzZXQgMSIsIHhsYWIgPSAiSXRlcmF0aW9uIiwgeWxhYiA9ICJWYWx1ZSIpCgojIEFkZCBhIGhvcml6b250YWwgbGluZSBmb3IgdGhlIGF2ZXJhZ2UKYWJsaW5lKGggPSBhdmVyYWdlLCBjb2wgPSAicmVkIiwgbHdkID0gMikKCmBgYAoKIyMjIEJpZHMgYW5kIEFza3MgT3ZlcmFsbAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBlbXB0eSB2ZWN0b3JzIHRvIHN0b3JlIHRoZSBCaWQgYW5kIEFzayB2YWx1ZXMKQmlkc19zZXQxIDwtIG51bWVyaWMoKQpBc2tzX3NldDEgPC0gbnVtZXJpYygpCgojIExvb3AgdGhyb3VnaCBlYWNoIGl0ZXJhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgQmlkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfMSBkYXRhZnJhbWUKICBCaWRfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCA0XSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBFeHRyYWN0IEFzayB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzEgZGF0YWZyYW1lIChuZXh0IGNvbHVtbikKICBBc2tfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCA1XSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBBcHBlbmQgdGhlIEJpZCBhbmQgQXNrIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIHZlY3RvcnMKICBCaWRzX3NldDEgPC0gYyhCaWRzX3NldDEsIGFzLm51bWVyaWMoQmlkX3NldDEpKQogIEFza3Nfc2V0MSA8LSBjKEFza3Nfc2V0MSwgYXMubnVtZXJpYyhBc2tfc2V0MSkpCn0KCiMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIEJpZCBhbmQgQXNrIHZhbHVlcwphdmVyYWdlX2JpZHMgPC0gbWVhbihCaWRzX3NldDEsIG5hLnJtID0gVFJVRSkKYXZlcmFnZV9hc2tzIDwtIG1lYW4oQXNrc19zZXQxLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIEJpZCBhbmQgQXNrIHZhbHVlcyBvbiB0aGUgc2FtZSBwbG90CnBsb3QoQmlkc19zZXQxLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIkJpZHMgdnMgQXNrcyBpbiBzZXQgMSIsIHhsYWIgPSAiSXRlcmF0aW9uIiwgeWxhYiA9ICJWYWx1ZSIpCmxpbmVzKEFza3Nfc2V0MSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQoKIyBBZGQgaG9yaXpvbnRhbCBsaW5lcyBmb3IgdGhlIGF2ZXJhZ2VzCmFibGluZShoID0gYXZlcmFnZV9iaWRzLCBjb2wgPSAiYmx1ZSIsIGx0eSA9IDEpCmFibGluZShoID0gYXZlcmFnZV9hc2tzLCBjb2wgPSAicmVkIiwgbHR5ID0gMSkKCmBgYAoKIyMjIFN0YXJ0IEZyb20gSGVyZQoKCiMjIHNldCAxICg2IGluZm9ybWVkKQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfYmlkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2FzayA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQmlkc19zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0MSwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9iaWRbaSwgbl0gPC0gbWVhbihCaWRzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2Fza1tpLCBuXSA8LSBtZWFuKEFza3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfYmlkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYmlkLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9hc2sgPC0gcm93TWVhbnMoYXZlcmFnZV9hc2ssIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIkJpZHMiLCAiQXNrcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWQxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZDJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkM19wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWQ0X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZDVfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkNl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDZdKSksICIsICIpCgogIEluZm9ybWVkMV9wbmxfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCA4XSkpLCAiLCAiKQogIAogIEluZm9ybWVkMl9wbmxfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAxMF0pKSwgIiwgIikKICAKICBJbmZvcm1lZDNfcG5sX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgMTJdKSksICIsICIpCiAgCiAgSW5mb3JtZWQ0X3BubF9zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDE0XSkpLCAiLCAiKQogIAogIEluZm9ybWVkNV9wbmxfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAxNl0pKSwgIiwgIikKICAKICBJbmZvcm1lZDZfcG5sX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQxLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWQxX3BubCA8LSBzYXBwbHkoSW5mb3JtZWQxX3BubF9zZXQxLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWQyX3BubCA8LSBzYXBwbHkoSW5mb3JtZWQyX3BubF9zZXQxLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWQzX3BubCA8LSBzYXBwbHkoSW5mb3JtZWQzX3BubF9zZXQxLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWQ0X3BubCA8LSBzYXBwbHkoSW5mb3JtZWQ0X3BubF9zZXQxLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWQ1X3BubCA8LSBzYXBwbHkoSW5mb3JtZWQ1X3BubF9zZXQxLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWQ2X3BubCA8LSBzYXBwbHkoSW5mb3JtZWQ2X3BubF9zZXQxLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZDFfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZDJfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWQyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZDNfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWQzX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZDRfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWQ0X3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZDVfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWQ1X3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZDZfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWQ2X3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWQyX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQzX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkM19wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNF9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZDRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDVfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWQ1X3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ2X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkNl9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQzX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDVfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ2X3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDZfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQyX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDNfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ1X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ2X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCAxIiwgIkluZm9ybWVkIDIiLCAiSW5mb3JtZWQgMyIsICJJbmZvcm1lZCA0IiwgIkluZm9ybWVkIDUiLCAiSW5mb3JtZWQgNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZDFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkMl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWQzX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZDRfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkNV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWQ2X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG9zX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgN10pKSwgIiwgIikKCiAgSW5mb3JtZWQxX3Bvc19zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDldKSksICIsICIpCiAgCiAgSW5mb3JtZWQyX3Bvc19zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDExXSkpLCAiLCAiKQogIAogIEluZm9ybWVkM19wb3Nfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAxM10pKSwgIiwgIikKICAKICBJbmZvcm1lZDRfcG9zX3NldDEgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzFbbiwgMTVdKSksICIsICIpCiAgCiAgSW5mb3JtZWQ1X3Bvc19zZXQxIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18xW24sIDE3XSkpLCAiLCAiKQogIAogIEluZm9ybWVkNl9wb3Nfc2V0MSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMVtuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDFfcG9zIDwtIHNhcHBseShJbmZvcm1lZDFfcG9zX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDJfcG9zIDwtIHNhcHBseShJbmZvcm1lZDJfcG9zX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDNfcG9zIDwtIHNhcHBseShJbmZvcm1lZDNfcG9zX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDRfcG9zIDwtIHNhcHBseShJbmZvcm1lZDRfcG9zX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDVfcG9zIDwtIHNhcHBseShJbmZvcm1lZDVfcG9zX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZDZfcG9zIDwtIHNhcHBseShJbmZvcm1lZDZfcG9zX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG9zW2ksIG5dIDwtIG1lYW4oTU1fcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkMV9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkMl9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkM19wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDNfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkNF9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDRfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkNV9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDVfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkNl9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZDZfcG9zLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkMV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZDJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDNfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWQzX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ0X3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkNF9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZDVfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDZfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWQ2X3BvcywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX01NX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibGFjayIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIFBvc2l0aW9uIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkM19wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ1X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNl9wb3MpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQzX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZDVfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ2X3BvcykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkMl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQzX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWQ0X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkNl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQgMSIsICJJbmZvcm1lZCAyIiwgIkluZm9ybWVkIDMiLCAiSW5mb3JtZWQgNCIsICJJbmZvcm1lZCA1IiwgIkluZm9ybWVkIDYiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgoKIyMgc2V0IDIgKDEgSW5mb3JtZWQgKyAxIG5vaXN5IGluZm9ybWVkICsgMSBub2lzeSArIDEgc3RvY2hhc3RpYyBub2lzeSArIDEgbXIgKyAxIG1vbSkKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDEsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfYXNrLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9tcl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfbW9tX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG5sX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgNl0pKSwgIiwgIikKCiAgSW5mb3JtZWRfcG5sX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgOF0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkX3BubF9zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDEwXSkpLCAiLCAiKQogIAogIE5vaXN5X3BubF9zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDEyXSkpLCAiLCAiKQogIAogIFN0b2NoTm9pc3lfcG5sX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgMTRdKSksICIsICIpCiAgCiAgbXJfcG5sX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgMTZdKSksICIsICIpCiAgCiAgbW9tX3BubF9zZXQyIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18yW24sIDE4XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgTU1fcG5sIDwtIHNhcHBseShNTV9wbmxfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkX3BubCA8LSBzYXBwbHkoSW5mb3JtZWRfcG5sX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkX3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZF9wbmxfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5X3BubCA8LSBzYXBwbHkoTm9pc3lfcG5sX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBTdG9jaE5vaXN5X3BubCA8LSBzYXBwbHkoU3RvY2hOb2lzeV9wbmxfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIG1yX3BubCA8LSBzYXBwbHkobXJfcG5sX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBtb21fcG5sIDwtIHNhcHBseShtb21fcG5sX3NldDIsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG5sW2ksIG5dIDwtIG1lYW4oTU1fcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkX3BubFtpLCBuXSA8LSBtZWFuKEluZm9ybWVkX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5X3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5X3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9TdG9jaE5vaXN5X3BubFtpLCBuXSA8LSBtZWFuKFN0b2NoTm9pc3lfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX21yX3BubFtpLCBuXSA8LSBtZWFuKG1yX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tb21fcG5sW2ksIG5dIDwtIG1lYW4obW9tX3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZF9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX1N0b2NoTm9pc3lfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9tcl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9tcl9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX21vbV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9tb21fcG5sLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUE5MIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5X3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbXJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tX3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5X3BubCwgb3ZlcmFsbF9hdmVyYWdlX21yX3BubCwgb3ZlcmFsbF9hdmVyYWdlX21vbV9wbmwpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9tcl9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21vbV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgSW5mb3JtZWQiLCAiTm9pc3kiLCAiU3RvY2hhc3RpYyBOb2lzeSIsICJNZWFuIFJldmVyc2lvbiIsICJNb21lbnR1bSIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZF9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZF9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3lfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21yX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9tb21fcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wb3Nfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCA3XSkpLCAiLCAiKQoKICBJbmZvcm1lZF9wb3Nfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCA5XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWRfcG9zX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgMTFdKSksICIsICIpCiAgCiAgTm9pc3lfcG9zX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgMTNdKSksICIsICIpCiAgCiAgU3RvY2hOb2lzeV9wb3Nfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAxNV0pKSwgIiwgIikKICAKICBtcl9wb3Nfc2V0MiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfMltuLCAxN10pKSwgIiwgIikKICAKICBtb21fcG9zX3NldDIgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzJbbiwgMTldKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wb3MgPC0gc2FwcGx5KE1NX3Bvc19zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG9zIDwtIHNhcHBseShJbmZvcm1lZF9wb3Nfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWRfcG9zIDwtIHNhcHBseShOb2lzeUluZm9ybWVkX3Bvc19zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lfcG9zIDwtIHNhcHBseShOb2lzeV9wb3Nfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3lfcG9zIDwtIHNhcHBseShTdG9jaE5vaXN5X3Bvc19zZXQyLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbXJfcG9zIDwtIHNhcHBseShtcl9wb3Nfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIG1vbV9wb3MgPC0gc2FwcGx5KG1vbV9wb3Nfc2V0MiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wb3NbaSwgbl0gPC0gbWVhbihNTV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWRfcG9zW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWRfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWRfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3lfcG9zW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfbXJfcG9zW2ksIG5dIDwtIG1lYW4obXJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX21vbV9wb3NbaSwgbl0gPC0gbWVhbihtb21fcG9zLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWRfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX21yX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX21yX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbW9tX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX21vbV9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21yX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21vbV9wb3MpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tcl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tb21fcG9zKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfbXJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9tb21fcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIiwgIk5vaXN5IEluZm9ybWVkIiwgIk5vaXN5IiwgIlN0b2NoYXN0aWMgTm9pc3kiLCAiTWVhbiBSZXZlcnNpb24iLCAiTW9tZW50dW0iKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgojIyBzZXQgMyAoMiBzdG9jaGFzdGljIG5vaXN5ICsgMiBtciArIDIgbW9tKQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX2JpZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9hc2sgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEJpZHNfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCA0XSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQXNrc19zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDVdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBCaWRzIDwtIHNhcHBseShCaWRzX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBBc2tzIDwtIHNhcHBseShBc2tzX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfYmlkW2ksIG5dIDwtIG1lYW4oQmlkcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9hc2tbaSwgbl0gPC0gbWVhbihBc2tzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX2JpZCA8LSByb3dNZWFucyhhdmVyYWdlX2JpZCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfYXNrIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYXNrLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfYmlkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBCaWRzIHZzIEFza3MiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfYXNrLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJCaWRzIiwgIkFza3MiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfU3RvY2hOb2lzeTFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3kyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9tcjFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21yMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfbW9tMV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfbW9tMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDZdKSksICIsICIpCgogIFN0b2NoTm9pc3kxX3BubF9zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDhdKSksICIsICIpCiAgCiAgU3RvY2hOb2lzeTJfcG5sX3NldDMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzNbbiwgMTBdKSksICIsICIpCiAgCiAgbXIxX3BubF9zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDEyXSkpLCAiLCAiKQogIAogIG1yMl9wbmxfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAxNF0pKSwgIiwgIikKICAKICBtb20xX3BubF9zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDE2XSkpLCAiLCAiKQogIAogIG1vbTJfcG5sX3NldDMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzNbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgU3RvY2hOb2lzeTFfcG5sIDwtIHNhcHBseShTdG9jaE5vaXN5MV9wbmxfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3kyX3BubCA8LSBzYXBwbHkoU3RvY2hOb2lzeTJfcG5sX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBtcjFfcG5sIDwtIHNhcHBseShtcjFfcG5sX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBtcjJfcG5sIDwtIHNhcHBseShtcjJfcG5sX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBtb20xX3BubCA8LSBzYXBwbHkobW9tMV9wbmxfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIG1vbTJfcG5sIDwtIHNhcHBseShtb20yX3BubF9zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9TdG9jaE5vaXN5MV9wbmxbaSwgbl0gPC0gbWVhbihTdG9jaE5vaXN5MV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfU3RvY2hOb2lzeTJfcG5sW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeTJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX21yMV9wbmxbaSwgbl0gPC0gbWVhbihtcjFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX21yMl9wbmxbaSwgbl0gPC0gbWVhbihtcjJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX21vbTFfcG5sW2ksIG5dIDwtIG1lYW4obW9tMV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfbW9tMl9wbmxbaSwgbl0gPC0gbWVhbihtb20yX3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX1N0b2NoTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeTJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9tcjFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfbXIxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbXIyX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX21yMl9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX21vbTFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfbW9tMV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX21vbTJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfbW9tMl9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX21yMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9tcjJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9tb20yX3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfbXIxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX21yMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9tb20xX3BubCwgb3ZlcmFsbF9hdmVyYWdlX21vbTJfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Ml9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfbXIxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfbXIyX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21vbTFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9tb20yX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJTdG9jaGFzdGljIE5vaXN5IDEiLCAiU3RvY2hhc3RpYyBOb2lzeSAyIiwgIk1lYW4gUmV2ZXJzaW9uIDEiLCAiTWVhbiBSZXZlcnNpb24gMiIsICJNb21lbnR1bSAxIiwgIk1vbWVudHVtIDIiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX1N0b2NoTm9pc3kxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5Ml9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfbXIxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9tcjJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21vbTFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX21vbTJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wb3Nfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCA3XSkpLCAiLCAiKQoKICBTdG9jaE5vaXN5MV9wb3Nfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCA5XSkpLCAiLCAiKQogIAogIFN0b2NoTm9pc3kyX3Bvc19zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDExXSkpLCAiLCAiKQogIAogIG1yMV9wb3Nfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAxMl0pKSwgIiwgIikKICAKICBtcjJfcG9zX3NldDMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzNbbiwgMTVdKSksICIsICIpCiAgCiAgbW9tMV9wb3Nfc2V0MyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfM1tuLCAxN10pKSwgIiwgIikKICAKICBtb20yX3Bvc19zZXQzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c18zW24sIDE5XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgTU1fcG9zIDwtIHNhcHBseShNTV9wb3Nfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3kxX3BvcyA8LSBzYXBwbHkoU3RvY2hOb2lzeTFfcG9zX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBTdG9jaE5vaXN5Ml9wb3MgPC0gc2FwcGx5KFN0b2NoTm9pc3kyX3Bvc19zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbXIxX3BvcyA8LSBzYXBwbHkobXIxX3Bvc19zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbXIyX3BvcyA8LSBzYXBwbHkobXIyX3Bvc19zZXQzLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgbW9tMV9wb3MgPC0gc2FwcGx5KG1vbTFfcG9zX3NldDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBtb20yX3BvcyA8LSBzYXBwbHkobW9tMl9wb3Nfc2V0MywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wb3NbaSwgbl0gPC0gbWVhbihNTV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfU3RvY2hOb2lzeTFfcG9zW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3kyX3Bvc1tpLCBuXSA8LSBtZWFuKFN0b2NoTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tcjFfcG9zW2ksIG5dIDwtIG1lYW4obXIxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tcjJfcG9zW2ksIG5dIDwtIG1lYW4obXIyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9tb20xX3Bvc1tpLCBuXSA8LSBtZWFuKG1vbTFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX21vbTJfcG9zW2ksIG5dIDwtIG1lYW4obW9tMl9wb3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5MV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9TdG9jaE5vaXN5MV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kyX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX1N0b2NoTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfbXIxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX21yMV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX21yMl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9tcjJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9tb20xX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX21vbTFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9tb20yX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX21vbTJfcG9zLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUG9zaXRpb24iLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21yMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tcjJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfbW9tMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tb20yX3BvcykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfbXIxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21yMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9tb20xX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX21vbTJfcG9zKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeTFfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5Ml9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfbXIxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfbXIyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX21vbTFfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9tb20yX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJTdG9jaGFzdGljIE5vaXN5IDEiLCAiU3RvY2hhc3RpYyBOb2lzeSAyIiwgIk1lYW4gUmV2ZXJzaW9uIDEiLCAiTWVhbiBSZXZlcnNpb24gMiIsICJNb21lbnR1bSAxIiwgIk1vbWVudHVtIDIiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgoKIyMgc2V0IDQgKDEgaW5mb3JtZWQgKyAyIG5vaXN5IGluZm9ybWVkICsgMiBub2lzeSArIDEgc3RvY2hhc3RpYyBub2lzeSkKCmBgYHtyfQojIEluaXRpYWxpemUgZW1wdHkgdmVjdG9ycyB0byBzdG9yZSB0cnVlIGFuZCBleHBlY3RlZCB2YWx1ZXMKVHJ1ZVZhbHVlc19zZXQ0IDwtIG51bWVyaWMoKQpFeHBlY3RlZFZhbHVlc19zZXQ0IDwtIG51bWVyaWMoKQoKIyBMb29wIHRocm91Z2ggZWFjaCBpdGVyYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c18xIGRhdGFmcmFtZQogIFRydWVWYWx1ZV9zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDJdKSksICIsICIpW1sxXV0KICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c18xIGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAzXSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBBcHBlbmQgdGhlIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIHZlY3RvcnMKICBUcnVlVmFsdWVzX3NldDQgPC0gYyhUcnVlVmFsdWVzX3NldDQsIGFzLm51bWVyaWMoVHJ1ZVZhbHVlX3NldDQpKQogIEV4cGVjdGVkVmFsdWVzX3NldDQgPC0gYyhFeHBlY3RlZFZhbHVlc19zZXQ0LCBhcy5udW1lcmljKEV4cGVjdGVkVmFsdWVfc2V0NCkpCn0KCiMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgdmFsdWVzCmF2ZXJhZ2VfdHJ1ZSA8LSBtZWFuKFRydWVWYWx1ZXNfc2V0NCkKCiMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIEV4cGVjdGVkIHZhbHVlcwphdmVyYWdlX2V4cGVjdGVkIDwtIG1lYW4oRXhwZWN0ZWRWYWx1ZXNfc2V0NCkKCiMgUGxvdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgb24gdGhlIHNhbWUgcGxvdApwbG90KFRydWVWYWx1ZXNfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyBpbiBzZXQgNCIsIHhsYWIgPSAiSXRlcmF0aW9uIiwgeWxhYiA9ICJWYWx1ZSIpCmxpbmVzKEV4cGVjdGVkVmFsdWVzX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgQWRkIGhvcml6b250YWwgbGluZXMgZm9yIHRoZSBhdmVyYWdlcwphYmxpbmUoaCA9IGF2ZXJhZ2VfdHJ1ZSwgY29sID0gImJsdWUiLCBsd2QgPSAxKQphYmxpbmUoaCA9IGF2ZXJhZ2VfZXhwZWN0ZWQsIGNvbCA9ICJyZWQiLCBsd2QgPSAxKQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgpgYGAKCgoKCmBgYHtyfQojIEluaXRpYWxpemUgZW1wdHkgdmVjdG9ycyB0byBzdG9yZSB0aGUgQmlkIGFuZCBBc2sgdmFsdWVzCkJpZHNfc2V0NCA8LSBudW1lcmljKCkKQXNrc19zZXQ0IDwtIG51bWVyaWMoKQoKIyBMb29wIHRocm91Z2ggZWFjaCBpdGVyYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IEJpZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzEgZGF0YWZyYW1lCiAgQmlkX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgNF0pKSwgIiwgIilbWzFdXQogIAogICMgRXh0cmFjdCBBc2sgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c18xIGRhdGFmcmFtZSAobmV4dCBjb2x1bW4pCiAgQXNrX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgNV0pKSwgIiwgIilbWzFdXQogIAogICMgQXBwZW5kIHRoZSBCaWQgYW5kIEFzayB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSB2ZWN0b3JzCiAgQmlkc19zZXQ0IDwtIGMoQmlkc19zZXQ0LCBhcy5udW1lcmljKEJpZF9zZXQ0KSkKICBBc2tzX3NldDQgPC0gYyhBc2tzX3NldDQsIGFzLm51bWVyaWMoQXNrX3NldDQpKQp9CgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBCaWQgYW5kIEFzayB2YWx1ZXMKYXZlcmFnZV9iaWRzIDwtIG1lYW4oQmlkc19zZXQ0LCBuYS5ybSA9IFRSVUUpCmF2ZXJhZ2VfYXNrcyA8LSBtZWFuKEFza3Nfc2V0NCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBCaWQgYW5kIEFzayB2YWx1ZXMgb24gdGhlIHNhbWUgcGxvdApwbG90KEJpZHNfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJCaWRzIHZzIEFza3MgaW4gc2V0IDQiLCB4bGFiID0gIkl0ZXJhdGlvbiIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhCaWRzX3NldDQsIEFza3Nfc2V0NCkpLCBtYXgoYyhCaWRzX3NldDQsIEFza3Nfc2V0NCkpKSkKbGluZXMoQXNrc19zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIkJpZHMiLCAiQXNrcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIEFkZCBob3Jpem9udGFsIGxpbmVzIGZvciB0aGUgYXZlcmFnZXMKYWJsaW5lKGggPSBhdmVyYWdlX2JpZHMsIGNvbCA9ICJibHVlIiwgbHR5ID0gMSkKYWJsaW5lKGggPSBhdmVyYWdlX2Fza3MsIGNvbCA9ICJyZWQiLCBsdHkgPSAxKQpgYGAKCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfYmlkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2FzayA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQmlkc19zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9iaWRbaSwgbl0gPC0gbWVhbihCaWRzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2Fza1tpLCBuXSA8LSBtZWFuKEFza3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfYmlkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYmlkLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9hc2sgPC0gcm93TWVhbnMoYXZlcmFnZV9hc2ssIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIkJpZHMiLCAiQXNrcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCgpgYGB7cn0KIyBJbml0aWFsaXplIGVtcHR5IHZlY3RvcnMgdG8gc3RvcmUgdGhlIEJpZCBhbmQgQXNrIHZhbHVlcwpNTV9wbmxfc2V0NCA8LSBudW1lcmljKCkKSW5mb3JtZWRfcG5sX3NldDQgPC0gbnVtZXJpYygpCk5vaXN5SW5mb3JtZWQxX3BubF9zZXQ0IDwtIG51bWVyaWMoKQpOb2lzeUluZm9ybWVkMl9wbmxfc2V0NCA8LSBudW1lcmljKCkKTm9pc3kxX3BubF9zZXQ0IDwtIG51bWVyaWMoKQpOb2lzeTJfcG5sX3NldDQgPC0gbnVtZXJpYygpClN0b2NoTm9pc3lfcG5sX3NldDQgPC0gbnVtZXJpYygpCgojIExvb3AgdGhyb3VnaCBlYWNoIGl0ZXJhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG5sX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCA2XSkpLCAiLCAiKVtbMV1dCiAgCiAgSW5mb3JtZWRfcG5sX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCA4XSkpLCAiLCAiKVtbMV1dCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG5sX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxMF0pKSwgIiwgIilbWzFdXQogIAogIE5vaXN5SW5mb3JtZWQyX3BubF92YWx1ZXMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTJdKSksICIsICIpW1sxXV0KICAKICBOb2lzeTFfcG5sX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxNF0pKSwgIiwgIilbWzFdXQogIAogIE5vaXN5Ml9wbmxfdmFsdWVzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDE2XSkpLCAiLCAiKVtbMV1dCiAgCiAgU3RvY2hOb2lzeV9wbmxfdmFsdWVzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDE4XSkpLCAiLCAiKVtbMV1dCiAgCiAgIyBDb252ZXJ0IEJpZCBhbmQgQXNrIHZhbHVlcyB0byBudW1lcmljIGFuZCBhcHBlbmQgdG8gdGhlIHZlY3RvcnMKICBNTV9wbmxfc2V0NCA8LSBjKE1NX3BubF9zZXQ0LCBhcy5udW1lcmljKE1NX3BubF92YWx1ZXMpKQogIEluZm9ybWVkX3BubF9zZXQ0IDwtIGMoSW5mb3JtZWRfcG5sX3NldDQsIGFzLm51bWVyaWMoSW5mb3JtZWRfcG5sX3ZhbHVlcykpCiAgTm9pc3lJbmZvcm1lZDFfcG5sX3NldDQgPC0gYyhOb2lzeUluZm9ybWVkMV9wbmxfc2V0NCwgYXMubnVtZXJpYyhOb2lzeUluZm9ybWVkMV9wbmxfdmFsdWVzKSkKICBOb2lzeUluZm9ybWVkMl9wbmxfc2V0NCA8LSBjKE5vaXN5SW5mb3JtZWQyX3BubF9zZXQ0LCBhcy5udW1lcmljKE5vaXN5SW5mb3JtZWQyX3BubF92YWx1ZXMpKQogIE5vaXN5MV9wbmxfc2V0NCA8LSBjKE5vaXN5X3BubF9zZXQ0LCBhcy5udW1lcmljKE5vaXN5MV9wbmxfdmFsdWVzKSkKICBOb2lzeTJfcG5sX3NldDQgPC0gYyhOb2lzeTJfcG5sX3NldDQsIGFzLm51bWVyaWMoTm9pc3kyX3BubF92YWx1ZXMpKQogIFN0b2NoTm9pc3lfcG5sX3NldDQgPC0gYyhTdG9jaE5vaXN5X3BubF9zZXQ0LCBhcy5udW1lcmljKFN0b2NoTm9pc3lfcG5sX3ZhbHVlcykpCn0KCiMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIEJpZCBhbmQgQXNrIHZhbHVlcwojYXZlcmFnZV9NTSA8LSBtZWFuKE1NX3NldDQsIG5hLnJtID0gVFJVRSkKI2F2ZXJhZ2VfSU4gPC0gbWVhbihJTl9zZXQ0LCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIEJpZCBhbmQgQXNrIHZhbHVlcyBvbiB0aGUgc2FtZSBwbG90CnBsb3QoTU1fcG5sX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIlBOTCBpbiBzZXQgNCIsIHhsYWIgPSAiSXRlcmF0aW9uIiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKE1NX3BubF9zZXQ0LCBJbmZvcm1lZF9wbmxfc2V0NCwgTm9pc3lJbmZvcm1lZDFfcG5sX3NldDQsIE5vaXN5SW5mb3JtZWQyX3BubF9zZXQ0LCBOb2lzeTFfcG5sX3NldDQsIE5vaXN5Ml9wbmxfc2V0NCwgU3RvY2hOb2lzeV9wbmxfc2V0NCkpLCBtYXgoYyhNTV9wbmxfc2V0NCwgSW5mb3JtZWRfcG5sX3NldDQsIE5vaXN5SW5mb3JtZWQxX3BubF9zZXQ0LCBOb2lzeUluZm9ybWVkMl9wbmxfc2V0NCwgTm9pc3kxX3BubF9zZXQ0LCBOb2lzeTJfcG5sX3NldDQsIFN0b2NoTm9pc3lfcG5sX3NldDQpKSkpCmxpbmVzKEluZm9ybWVkX3BubF9zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKE5vaXN5SW5mb3JtZWQxX3BubF9zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMoTm9pc3lJbmZvcm1lZDJfcG5sX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMoTm9pc3kxX3BubF9zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhOb2lzeTJfcG5sX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMoU3RvY2hOb2lzeV9wbmxfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbXJpZ2h0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIiwgIk5vaXN5IEluZm9ybWVkIDEiLCAiTm9pc3kgSW5mb3JtZWQgMiIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiU3RvY2hhc3RpYyBOb2lzeSIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCgojIEFkZCBob3Jpem9udGFsIGxpbmVzIGZvciB0aGUgYXZlcmFnZXMKI2FibGluZShoID0gYXZlcmFnZV9NTSwgY29sID0gImJsdWUiLCBsdHkgPSAxKQojYWJsaW5lKGggPSBhdmVyYWdlX0lOLCBjb2wgPSAicmVkIiwgbHR5ID0gMSkKCmBgYAoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZF9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTFfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5Ml9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfU3RvY2hOb2lzeV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDZdKSksICIsICIpCgogIEluZm9ybWVkX3BubF9zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDhdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG5sX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTBdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG5sX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTJdKSksICIsICIpCiAgCiAgTm9pc3kxX3BubF9zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDE0XSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wbmxfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxNl0pKSwgIiwgIikKICAKICBTdG9jaE5vaXN5X3BubF9zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDE4XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgTU1fcG5sIDwtIHNhcHBseShNTV9wbmxfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkX3BubCA8LSBzYXBwbHkoSW5mb3JtZWRfcG5sX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMV9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQxX3BubF9zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDJfcG5sIDwtIHNhcHBseShOb2lzeUluZm9ybWVkMl9wbmxfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5MV9wbmwgPC0gc2FwcGx5KE5vaXN5MV9wbmxfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5Ml9wbmwgPC0gc2FwcGx5KE5vaXN5Ml9wbmxfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIFN0b2NoTm9pc3lfcG5sIDwtIHNhcHBseShTdG9jaE5vaXN5X3BubF9zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTFfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTJfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9TdG9jaE5vaXN5X3BubFtpLCBuXSA8LSBtZWFuKFN0b2NoTm9pc3lfcG5sLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5MV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX1N0b2NoTm9pc3lfcG5sLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUE5MIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG5sKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfU3RvY2hOb2lzeV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgSW5mb3JtZWQgMSIsICJOb2lzeSBJbmZvcm1lZCAyIiwgIk5vaXN5IDEiLCAiTm9pc3kgMiIsICJTdG9jaGFzdGljIE5vaXN5IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBlbXB0eSB2ZWN0b3JzIHRvIHN0b3JlIHRoZSBCaWQgYW5kIEFzayB2YWx1ZXMKTU1fcG9zX3NldDQgPC0gbnVtZXJpYygpCkluZm9ybWVkX3Bvc19zZXQ0IDwtIG51bWVyaWMoKQpOb2lzeUluZm9ybWVkMV9wb3Nfc2V0NCA8LSBudW1lcmljKCkKTm9pc3lJbmZvcm1lZDJfcG9zX3NldDQgPC0gbnVtZXJpYygpCk5vaXN5MV9wb3Nfc2V0NCA8LSBudW1lcmljKCkKTm9pc3kyX3Bvc19zZXQ0IDwtIG51bWVyaWMoKQpTdG9jaE5vaXN5X3Bvc19zZXQ0IDwtIG51bWVyaWMoKQoKIyBMb29wIHRocm91Z2ggZWFjaCBpdGVyYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc192YWx1ZXMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgN10pKSwgIiwgIilbWzFdXQogIAogIEluZm9ybWVkX3Bvc192YWx1ZXMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgOV0pKSwgIiwgIilbWzFdXQogIAogIE5vaXN5SW5mb3JtZWQxX3Bvc192YWx1ZXMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTFdKSksICIsICIpW1sxXV0KICAKICBOb2lzeUluZm9ybWVkMl9wb3NfdmFsdWVzIDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDEzXSkpLCAiLCAiKVtbMV1dCiAgCiAgTm9pc3kxX3Bvc192YWx1ZXMgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTVdKSksICIsICIpW1sxXV0KICAKICBOb2lzeTJfcG9zX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxN10pKSwgIiwgIilbWzFdXQogIAogIFN0b2NoTm9pc3lfcG9zX3ZhbHVlcyA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxOV0pKSwgIiwgIilbWzFdXQogIAogICMgQ29udmVydCBCaWQgYW5kIEFzayB2YWx1ZXMgdG8gbnVtZXJpYyBhbmQgYXBwZW5kIHRvIHRoZSB2ZWN0b3JzCiAgTU1fcG9zX3NldDQgPC0gYyhNTV9wb3Nfc2V0NCwgYXMubnVtZXJpYyhNTV9wb3NfdmFsdWVzKSkKICBJbmZvcm1lZF9wb3Nfc2V0NCA8LSBjKEluZm9ybWVkX3Bvc19zZXQ0LCBhcy5udW1lcmljKEluZm9ybWVkX3Bvc192YWx1ZXMpKQogIE5vaXN5SW5mb3JtZWQxX3Bvc19zZXQ0IDwtIGMoTm9pc3lJbmZvcm1lZDFfcG9zX3NldDQsIGFzLm51bWVyaWMoTm9pc3lJbmZvcm1lZDFfcG9zX3ZhbHVlcykpCiAgTm9pc3lJbmZvcm1lZDJfcG9zX3NldDQgPC0gYyhOb2lzeUluZm9ybWVkMl9wb3Nfc2V0NCwgYXMubnVtZXJpYyhOb2lzeUluZm9ybWVkMl9wb3NfdmFsdWVzKSkKICBOb2lzeTFfcG9zX3NldDQgPC0gYyhOb2lzeV9wb3Nfc2V0NCwgYXMubnVtZXJpYyhOb2lzeTFfcG9zX3ZhbHVlcykpCiAgTm9pc3kyX3Bvc19zZXQ0IDwtIGMoTm9pc3kyX3Bvc19zZXQ0LCBhcy5udW1lcmljKE5vaXN5Ml9wb3NfdmFsdWVzKSkKICBTdG9jaE5vaXN5X3Bvc19zZXQ0IDwtIGMoU3RvY2hOb2lzeV9wb3Nfc2V0NCwgYXMubnVtZXJpYyhTdG9jaE5vaXN5X3Bvc192YWx1ZXMpKQp9CgojIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBCaWQgYW5kIEFzayB2YWx1ZXMKI2F2ZXJhZ2VfTU0gPC0gbWVhbihNTV9zZXQ0LCBuYS5ybSA9IFRSVUUpCiNhdmVyYWdlX0lOIDwtIG1lYW4oSU5fc2V0NCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBCaWQgYW5kIEFzayB2YWx1ZXMgb24gdGhlIHNhbWUgcGxvdApwbG90KE1NX3Bvc19zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJQb3NpdGlvbiBpbiBzZXQgNCIsIHhsYWIgPSAiSXRlcmF0aW9uIiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKE1NX3Bvc19zZXQ0LCBJbmZvcm1lZF9wb3Nfc2V0NCwgTm9pc3lJbmZvcm1lZDFfcG9zX3NldDQsIE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQ0LCBOb2lzeTFfcG9zX3NldDQsIE5vaXN5Ml9wb3Nfc2V0NCwgU3RvY2hOb2lzeV9wb3Nfc2V0NCkpLCBtYXgoYyhNTV9wb3Nfc2V0NCwgSW5mb3JtZWRfcG9zX3NldDQsIE5vaXN5SW5mb3JtZWQxX3Bvc19zZXQ0LCBOb2lzeUluZm9ybWVkMl9wb3Nfc2V0NCwgTm9pc3kxX3Bvc19zZXQ0LCBOb2lzeTJfcG9zX3NldDQsIFN0b2NoTm9pc3lfcG9zX3NldDQpKSkpCmxpbmVzKEluZm9ybWVkX3Bvc19zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKE5vaXN5SW5mb3JtZWQxX3Bvc19zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMoTm9pc3lJbmZvcm1lZDJfcG9zX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMoTm9pc3kxX3Bvc19zZXQ0LCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhOb2lzeTJfcG9zX3NldDQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMoU3RvY2hOb2lzeV9wb3Nfc2V0NCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKCiMgQWRkIGxlZ2VuZApsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgSW5mb3JtZWQgMSIsICJOb2lzeSBJbmZvcm1lZCAyIiwgIk5vaXN5IDEiLCAiTm9pc3kgMiIsICJTdG9jaGFzdGljIE5vaXN5IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKCiMgQWRkIGhvcml6b250YWwgbGluZXMgZm9yIHRoZSBhdmVyYWdlcwojYWJsaW5lKGggPSBhdmVyYWdlX01NLCBjb2wgPSAiYmx1ZSIsIGx0eSA9IDEpCiNhYmxpbmUoaCA9IGF2ZXJhZ2VfSU4sIGNvbCA9ICJyZWQiLCBsdHkgPSAxKQpgYGAKCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5MV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kyX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9TdG9jaE5vaXN5X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKCiAgTU1fcG9zX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgN10pKSwgIiwgIikKCiAgSW5mb3JtZWRfcG9zX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgOV0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkMV9wb3Nfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxMV0pKSwgIiwgIikKICAKICBOb2lzeUluZm9ybWVkMl9wb3Nfc2V0NCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNFtuLCAxM10pKSwgIiwgIikKICAKICBOb2lzeTFfcG9zX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTVdKSksICIsICIpCiAgCiAgTm9pc3kyX3Bvc19zZXQ0IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c180W24sIDE3XSkpLCAiLCAiKQogIAogIFN0b2NoTm9pc3lfcG9zX3NldDQgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgMTldKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wb3MgPC0gc2FwcGx5KE1NX3Bvc19zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG9zIDwtIHNhcHBseShJbmZvcm1lZF9wb3Nfc2V0NCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQxX3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDFfcG9zX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BvcyA8LSBzYXBwbHkoTm9pc3kxX3Bvc19zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BvcyA8LSBzYXBwbHkoTm9pc3kyX3Bvc19zZXQ0LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgU3RvY2hOb2lzeV9wb3MgPC0gc2FwcGx5KFN0b2NoTm9pc3lfcG9zX3NldDQsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfTU1fcG9zW2ksIG5dIDwtIG1lYW4oTU1fcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX0luZm9ybWVkX3Bvc1tpLCBuXSA8LSBtZWFuKEluZm9ybWVkX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5MV9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5Ml9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeTJfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX1N0b2NoTm9pc3lfcG9zW2ksIG5dIDwtIG1lYW4oU3RvY2hOb2lzeV9wb3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kxX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Ml9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfU3RvY2hOb2lzeV9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5X3BvcykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9TdG9jaE5vaXN5X3BvcykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX1N0b2NoTm9pc3lfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIiwgIk5vaXN5IEluZm9ybWVkIDEiLCAiTm9pc3kgSW5mb3JtZWQgMiIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiU3RvY2hhc3RpYyBOb2lzeSIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCgojIyBzZXQgNSAoTm9pc3kqNikKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV90cnVlIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2V4cGVjdGVkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBUcnVlVmFsdWVzX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMl0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEV4cGVjdGVkVmFsdWVzX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzRbbiwgM10pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIFRydWVfdmFsdWVzIDwtIHNhcHBseShUcnVlVmFsdWVzX3NldDUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBFeHBlY3RlZF92YWx1ZXMgPC0gc2FwcGx5KEV4cGVjdGVkVmFsdWVzX3NldDUsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICAKICAgICMgQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIG9mIFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIGF2ZXJhZ2VfdHJ1ZVtpLCBuXSA8LSBtZWFuKFRydWVfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2V4cGVjdGVkW2ksIG5dIDwtIG1lYW4oRXhwZWN0ZWRfdmFsdWVzLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX3RydWUgPC0gcm93TWVhbnMoYXZlcmFnZV90cnVlLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCA8LSByb3dNZWFucyhhdmVyYWdlX2V4cGVjdGVkLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgVHJ1ZSB2cyBFeHBlY3RlZCBWYWx1ZXMiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIlRydWUgVmFsdWVzIiwgIkV4cGVjdGVkIFZhbHVlcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX2JpZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgQmlkcyB2cyBBc2tzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5M19wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3k0X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTVfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5Nl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDZdKSksICIsICIpCgogIE5vaXN5MV9wbmxfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCA4XSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wbmxfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCAxMF0pKSwgIiwgIikKICAKICBOb2lzeTNfcG5sX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMTJdKSksICIsICIpCiAgCiAgTm9pc3k0X3BubF9zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDE0XSkpLCAiLCAiKQogIAogIE5vaXN5NV9wbmxfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCAxNl0pKSwgIiwgIikKICAKICBOb2lzeTZfcG5sX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BubCA8LSBzYXBwbHkoTm9pc3kxX3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BubCA8LSBzYXBwbHkoTm9pc3kyX3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kzX3BubCA8LSBzYXBwbHkoTm9pc3kzX3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k0X3BubCA8LSBzYXBwbHkoTm9pc3k0X3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k1X3BubCA8LSBzYXBwbHkoTm9pc3k1X3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k2X3BubCA8LSBzYXBwbHkoTm9pc3k2X3BubF9zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTFfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTJfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTNfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3kzX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTRfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3k0X3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTVfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3k1X3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTZfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3k2X3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5M19wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3k1X3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k2X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Nl9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k2X3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTZfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k2X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiTm9pc3kgMyIsICJOb2lzeSA0IiwgIk5vaXN5IDUiLCAiTm9pc3kgNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5M19wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3k0X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTVfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5Nl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDddKSksICIsICIpCgogIE5vaXN5MV9wb3Nfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCA5XSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wb3Nfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCAxMV0pKSwgIiwgIikKICAKICBOb2lzeTNfcG9zX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMTNdKSksICIsICIpCiAgCiAgTm9pc3k0X3Bvc19zZXQ1IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c181W24sIDE1XSkpLCAiLCAiKQogIAogIE5vaXN5NV9wb3Nfc2V0NSA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNVtuLCAxN10pKSwgIiwgIikKICAKICBOb2lzeTZfcG9zX3NldDUgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzVbbiwgMTldKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wb3MgPC0gc2FwcGx5KE1NX3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BvcyA8LSBzYXBwbHkoTm9pc3kxX3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BvcyA8LSBzYXBwbHkoTm9pc3kyX3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kzX3BvcyA8LSBzYXBwbHkoTm9pc3kzX3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k0X3BvcyA8LSBzYXBwbHkoTm9pc3k0X3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k1X3BvcyA8LSBzYXBwbHkoTm9pc3k1X3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k2X3BvcyA8LSBzYXBwbHkoTm9pc3k2X3Bvc19zZXQ1LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTFfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTJfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTNfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3kzX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTRfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3k0X3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTVfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3k1X3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeTZfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3k2X3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5M19wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTRfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3k1X3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k2X3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Nl9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k0X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTZfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Nl9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInB1cnBsZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTZfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21yaWdodCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiTm9pc3kgMyIsICJOb2lzeSA0IiwgIk5vaXN5IDUiLCAiTm9pc3kgNiIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCiMjIHNldDYgKDEgaW5mb3JtZWQgKyA1IG5vaXN5KQoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX3RydWUgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfZXhwZWN0ZWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CiAgIyBFeHRyYWN0IFRydWUgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIFRydWVWYWx1ZXNfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAyXSkpLCAiLCAiKQogIAogICMgRXh0cmFjdCBFeHBlY3RlZCB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgRXhwZWN0ZWRWYWx1ZXNfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAzXSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgVHJ1ZV92YWx1ZXMgPC0gc2FwcGx5KFRydWVWYWx1ZXNfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEV4cGVjdGVkX3ZhbHVlcyA8LSBzYXBwbHkoRXhwZWN0ZWRWYWx1ZXNfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV90cnVlW2ksIG5dIDwtIG1lYW4oVHJ1ZV92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfZXhwZWN0ZWRbaSwgbl0gPC0gbWVhbihFeHBlY3RlZF92YWx1ZXMsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSA8LSByb3dNZWFucyhhdmVyYWdlX3RydWUsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfZXhwZWN0ZWQsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV90cnVlLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBvZiBUcnVlIHZzIEV4cGVjdGVkIFZhbHVlcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfdHJ1ZSwgb3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiVHJ1ZSBWYWx1ZXMiLCAiRXhwZWN0ZWQgVmFsdWVzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX2JpZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgQmlkcyB2cyBBc2tzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKYGBge3J9CiMgSW5pdGlhbGl6ZSBtYXRyaWNlcyB0byBzdG9yZSBhdmVyYWdlcyBmb3IgZWFjaCBwb3NpdGlvbgphdmVyYWdlX01NX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9JbmZvcm1lZF9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5M19wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3k0X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTVfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wbmxfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCA2XSkpLCAiLCAiKQoKICBJbmZvcm1lZF9wbmxfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCA4XSkpLCAiLCAiKQogIAogIE5vaXN5MV9wbmxfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAxMF0pKSwgIiwgIikKICAKICBOb2lzeTJfcG5sX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgMTJdKSksICIsICIpCiAgCiAgTm9pc3kzX3BubF9zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDE0XSkpLCAiLCAiKQogIAogIE5vaXN5NF9wbmxfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAxNl0pKSwgIiwgIikKICAKICBOb2lzeTVfcG5sX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG5sIDwtIHNhcHBseShJbmZvcm1lZF9wbmxfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5MV9wbmwgPC0gc2FwcGx5KE5vaXN5MV9wbmxfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5Ml9wbmwgPC0gc2FwcGx5KE5vaXN5Ml9wbmxfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5M19wbmwgPC0gc2FwcGx5KE5vaXN5M19wbmxfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5NF9wbmwgPC0gc2FwcGx5KE5vaXN5NF9wbmxfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5NV9wbmwgPC0gc2FwcGx5KE5vaXN5NV9wbmxfc2V0NiwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wbmxbaSwgbl0gPC0gbWVhbihNTV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWRfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5MV9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeTFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5Ml9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeTJfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5M19wbmxbaSwgbl0gPC0gbWVhbihOb2lzeTNfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5NF9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeTRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5NV9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeTVfcG5sLCBuYS5ybSA9IFRSVUUpCiAgfQp9CgojIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBhdmVyYWdlIGZvciBlYWNoIHBvc2l0aW9uIGFjcm9zcyBhbGwgc2ltdWxhdGlvbnMKb3ZlcmFsbF9hdmVyYWdlX01NX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX01NX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfSW5mb3JtZWRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Ml9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTNfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTRfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3k0X3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5NV9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG5sKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3BubCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k0X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJOb2lzeSAxIiwgIk5vaXN5IDIiLCAiTm9pc3kgMyIsICJOb2lzeSA0IiwgIk5vaXN5IDUiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTFfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5Ml9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kzX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTRfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5NV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDddKSksICIsICIpCgogIEluZm9ybWVkX3Bvc19zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDldKSksICIsICIpCiAgCiAgTm9pc3kxX3Bvc19zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDExXSkpLCAiLCAiKQogIAogIE5vaXN5Ml9wb3Nfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAxM10pKSwgIiwgIikKICAKICBOb2lzeTNfcG9zX3NldDYgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzZbbiwgMTVdKSksICIsICIpCiAgCiAgTm9pc3k0X3Bvc19zZXQ2IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c182W24sIDE3XSkpLCAiLCAiKQogIAogIE5vaXN5NV9wb3Nfc2V0NiA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfNltuLCAxOV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIE1NX3BvcyA8LSBzYXBwbHkoTU1fcG9zX3NldDYsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBJbmZvcm1lZF9wb3MgPC0gc2FwcGx5KEluZm9ybWVkX3BubF9zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kxX3BvcyA8LSBzYXBwbHkoTm9pc3kxX3Bvc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kyX3BvcyA8LSBzYXBwbHkoTm9pc3kyX3Bvc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3kzX3BvcyA8LSBzYXBwbHkoTm9pc3kzX3Bvc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k0X3BvcyA8LSBzYXBwbHkoTm9pc3k0X3Bvc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3k1X3BvcyA8LSBzYXBwbHkoTm9pc3k1X3Bvc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kxX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5MV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kyX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5Ml9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kzX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5M19wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3k0X3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5NF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3k1X3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5NV9wb3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kyX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5M19wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTRfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTVfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3k1X3BvcywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX01NX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibGFjayIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIFBvc2l0aW9uIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k1X3BvcykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3k0X3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5NV9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5NF9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5NV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgMSIsICJOb2lzeSAyIiwgIk5vaXN5IDMiLCAiTm9pc3kgNCIsICJOb2lzeSA1IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgoKIyMgc2V0NyAoMSBpbmZvcm1lZCArIDUgbm9pc3kgaW5mb3JtZWQpCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfdHJ1ZSA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9leHBlY3RlZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX3RydWVbaSwgbl0gPC0gbWVhbihUcnVlX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9leHBlY3RlZFtpLCBuXSA8LSBtZWFuKEV4cGVjdGVkX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV90cnVlIDwtIHJvd01lYW5zKGF2ZXJhZ2VfdHJ1ZSwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQgPC0gcm93TWVhbnMoYXZlcmFnZV9leHBlY3RlZCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJUcnVlIFZhbHVlcyIsICJFeHBlY3RlZCBWYWx1ZXMiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfYmlkIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX2FzayA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgQmlkc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDRdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBBc2tzX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgNV0pKSwgIiwgIikKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIHBvc2l0aW9uIChpKQogIGZvciAoaSBpbiAxOjEwMCkgewogICAgIyBFeHRyYWN0IFRydWUgYW5kIEV4cGVjdGVkIHZhbHVlcyBmb3IgdGhlIGktdGggcG9zaXRpb24KICAgIEJpZHMgPC0gc2FwcGx5KEJpZHNfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEFza3MgPC0gc2FwcGx5KEFza3Nfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9iaWRbaSwgbl0gPC0gbWVhbihCaWRzLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX2Fza1tpLCBuXSA8LSBtZWFuKEFza3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfYmlkIDwtIHJvd01lYW5zKGF2ZXJhZ2VfYmlkLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9hc2sgPC0gcm93TWVhbnMoYXZlcmFnZV9hc2ssIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9iaWQsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIEJpZHMgdnMgQXNrcyIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfYmlkLCBvdmVyYWxsX2F2ZXJhZ2VfYXNrKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9hc2ssIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIkJpZHMiLCAiQXNrcyIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3BubF9zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDZdKSksICIsICIpCgogIEluZm9ybWVkX3BubF9zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDhdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTBdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTJdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDNfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTRdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDRfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTZdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDVfcG5sX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMThdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wbmwgPC0gc2FwcGx5KE1NX3BubF9zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG5sIDwtIHNhcHBseShJbmZvcm1lZF9wbmxfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQxX3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDFfcG5sX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3BubF9zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDNfcG5sIDwtIHNhcHBseShOb2lzeUluZm9ybWVkM19wbmxfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQ0X3BubCA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDRfcG5sX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkNV9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQ1X3BubF9zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3BubFtpLCBuXSA8LSBtZWFuKE1NX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wbmxbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQyX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wbmxbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkM19wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQ1X3BubCwgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wbmwsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQTkwiLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BubCkpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG5sKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNF9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJOb2lzeSBJbmZvcm1lZCAxIiwgIk5vaXN5IEluZm9ybWVkIDIiLCAiTm9pc3kgSW5mb3JtZWQgMyIsICJOb2lzeSBJbmZvcm1lZCA0IiwgIk5vaXN5IEluZm9ybWVkIDUiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9NTV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfSW5mb3JtZWRfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG9zIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BvcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wb3MgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCgojIExvb3AgdGhyb3VnaCBlYWNoIHNpbXVsYXRpb24gKG4pCmZvciAobiBpbiAxOjEwKSB7CgogIE1NX3Bvc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDddKSksICIsICIpCgogIEluZm9ybWVkX3Bvc19zZXQ3IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c183W24sIDldKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDFfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTFdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDJfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTNdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDNfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTVdKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDRfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTddKSksICIsICIpCiAgCiAgTm9pc3lJbmZvcm1lZDVfcG9zX3NldDcgPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzdbbiwgMTldKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBNTV9wb3MgPC0gc2FwcGx5KE1NX3Bvc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgSW5mb3JtZWRfcG9zIDwtIHNhcHBseShJbmZvcm1lZF9wb3Nfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQxX3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDFfcG9zX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMl9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDNfcG9zIDwtIHNhcHBseShOb2lzeUluZm9ybWVkM19wb3Nfc2V0NywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5SW5mb3JtZWQ0X3BvcyA8LSBzYXBwbHkoTm9pc3lJbmZvcm1lZDRfcG9zX3NldDcsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkNV9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQ1X3Bvc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX01NX3Bvc1tpLCBuXSA8LSBtZWFuKE1NX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9JbmZvcm1lZF9wb3NbaSwgbl0gPC0gbWVhbihJbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQyX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQyX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkM19wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zW2ksIG5dIDwtIG1lYW4oTm9pc3lJbmZvcm1lZDRfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQ1X3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQ1X3BvcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9NTV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9NTV9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX0luZm9ybWVkX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wb3MsIG5hLnJtID0gVFJVRSkKCiMgUGxvdCB0aGUgb3ZlcmFsbCBhdmVyYWdlcwpwbG90KG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmxhY2siLCBtYWluID0gIk92ZXJhbGwgQXZlcmFnZSBQb3NpdGlvbiIsIHhsYWIgPSAiUG9zaXRpb24gaW4gTGlzdCIsIHlsYWIgPSAiVmFsdWUiLCB5bGltID0gYyhtaW4oYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDNfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG9zKSksIG1heChjKG92ZXJhbGxfYXZlcmFnZV9NTV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkM19wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNF9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkNV9wb3MpKSkpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicmVkIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJncmVlbiIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAieWVsbG93IikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQzX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQ0X3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDVfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gIm9yYW5nZSIpCgojIEFkZCBsZWdlbmQKbGVnZW5kKCJib3R0b21sZWZ0IiwgbGVnZW5kID0gYygiTWFya2V0IE1ha2VyIiwgIkluZm9ybWVkIiwgIk5vaXN5IEluZm9ybWVkIDEiLCAiTm9pc3kgSW5mb3JtZWQgMiIsICJOb2lzeSBJbmZvcm1lZCAzIiwgIk5vaXN5IEluZm9ybWVkIDQiLCAiTm9pc3kgSW5mb3JtZWQgNSIpLCBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiZ3JlZW4iLCAieWVsbG93IiwgImJsdWUiLCAicHVycGxlIiwgIm9yYW5nZSIpLCBsdHkgPSAxLCBjZXggPSAwLjgpCmBgYAoKCgojIyBzZXQ4ICgxIGluZm9ybWVkICsgMiBub2lzeSBpbmZvcm1lZCArIDMgbm9pc3kpCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfdHJ1ZSA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9leHBlY3RlZCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKCiMgTG9vcCB0aHJvdWdoIGVhY2ggc2ltdWxhdGlvbiAobikKZm9yIChuIGluIDE6MTApIHsKICAjIEV4dHJhY3QgVHJ1ZSB2YWx1ZXMgZnJvbSB0aGUgYWdncmVnYXRlZF9yZXN1bHRzXzQgZGF0YWZyYW1lCiAgVHJ1ZVZhbHVlc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDJdKSksICIsICIpCiAgCiAgIyBFeHRyYWN0IEV4cGVjdGVkIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBFeHBlY3RlZFZhbHVlc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDNdKSksICIsICIpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCBwb3NpdGlvbiAoaSkKICBmb3IgKGkgaW4gMToxMDApIHsKICAgICMgRXh0cmFjdCBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBUcnVlX3ZhbHVlcyA8LSBzYXBwbHkoVHJ1ZVZhbHVlc19zZXQ3LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgRXhwZWN0ZWRfdmFsdWVzIDwtIHNhcHBseShFeHBlY3RlZFZhbHVlc19zZXQ2LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX3RydWVbaSwgbl0gPC0gbWVhbihUcnVlX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9leHBlY3RlZFtpLCBuXSA8LSBtZWFuKEV4cGVjdGVkX3ZhbHVlcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV90cnVlIDwtIHJvd01lYW5zKGF2ZXJhZ2VfdHJ1ZSwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQgPC0gcm93TWVhbnMoYXZlcmFnZV9leHBlY3RlZCwgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX3RydWUsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsIG1haW4gPSAiT3ZlcmFsbCBBdmVyYWdlIG9mIFRydWUgdnMgRXhwZWN0ZWQgVmFsdWVzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV90cnVlLCBvdmVyYWxsX2F2ZXJhZ2VfZXhwZWN0ZWQpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX3RydWUsIG92ZXJhbGxfYXZlcmFnZV9leHBlY3RlZCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2V4cGVjdGVkLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJUcnVlIFZhbHVlcyIsICJFeHBlY3RlZCBWYWx1ZXMiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCmBgYHtyfQojIEluaXRpYWxpemUgbWF0cmljZXMgdG8gc3RvcmUgYXZlcmFnZXMgZm9yIGVhY2ggcG9zaXRpb24KYXZlcmFnZV9iaWQgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfYXNrIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewogICMgRXh0cmFjdCBUcnVlIHZhbHVlcyBmcm9tIHRoZSBhZ2dyZWdhdGVkX3Jlc3VsdHNfNCBkYXRhZnJhbWUKICBCaWRzX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgNF0pKSwgIiwgIikKICAKICAjIEV4dHJhY3QgRXhwZWN0ZWQgdmFsdWVzIGZyb20gdGhlIGFnZ3JlZ2F0ZWRfcmVzdWx0c180IGRhdGFmcmFtZQogIEFza3Nfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCA1XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgQmlkcyA8LSBzYXBwbHkoQmlkc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgQXNrcyA8LSBzYXBwbHkoQXNrc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgCiAgICAjIENhbGN1bGF0ZSB0aGUgYXZlcmFnZSBvZiBUcnVlIGFuZCBFeHBlY3RlZCB2YWx1ZXMgZm9yIHRoZSBpLXRoIHBvc2l0aW9uCiAgICBhdmVyYWdlX2JpZFtpLCBuXSA8LSBtZWFuKEJpZHMsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfYXNrW2ksIG5dIDwtIG1lYW4oQXNrcywgbmEucm0gPSBUUlVFKQogIH0KfQoKIyBDYWxjdWxhdGUgdGhlIG92ZXJhbGwgYXZlcmFnZSBmb3IgZWFjaCBwb3NpdGlvbiBhY3Jvc3MgYWxsIHNpbXVsYXRpb25zCm92ZXJhbGxfYXZlcmFnZV9iaWQgPC0gcm93TWVhbnMoYXZlcmFnZV9iaWQsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX2FzayA8LSByb3dNZWFucyhhdmVyYWdlX2FzaywgbmEucm0gPSBUUlVFKQoKIyBQbG90IHRoZSBvdmVyYWxsIGF2ZXJhZ2VzCnBsb3Qob3ZlcmFsbF9hdmVyYWdlX2JpZCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2Ugb2YgQmlkcyB2cyBBc2tzIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9iaWQsIG92ZXJhbGxfYXZlcmFnZV9hc2spKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX2JpZCwgb3ZlcmFsbF9hdmVyYWdlX2FzaykpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX2FzaywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiQmlkcyIsICJBc2tzIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5MV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTNfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wbmxfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCA2XSkpLCAiLCAiKQoKICBJbmZvcm1lZF9wbmxfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCA4XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQxX3BubF9zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDEwXSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQyX3BubF9zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDEyXSkpLCAiLCAiKQogIAogIE5vaXN5MV9wbmxfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCAxNF0pKSwgIiwgIikKICAKICBOb2lzeTJfcG5sX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgMTZdKSksICIsICIpCiAgCiAgTm9pc3kzX3BubF9zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDE4XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgTU1fcG5sIDwtIHNhcHBseShNTV9wbmxfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkX3BubCA8LSBzYXBwbHkoSW5mb3JtZWRfcG5sX3NldDgsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMV9wbmwgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQxX3BubF9zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDJfcG5sIDwtIHNhcHBseShOb2lzeUluZm9ybWVkMl9wbmxfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5MV9wbmwgPC0gc2FwcGx5KE5vaXN5MV9wbmxfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5Ml9wbmwgPC0gc2FwcGx5KE5vaXN5Ml9wbmxfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5M19wbmwgPC0gc2FwcGx5KE5vaXN5M19wbmxfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wbmxbaSwgbl0gPC0gbWVhbihNTV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWRfcG5sW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWRfcG5sLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmxbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMl9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kxX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5MV9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kyX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5Ml9wbmwsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kzX3BubFtpLCBuXSA8LSBtZWFuKE5vaXN5M19wbmwsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kxX3BubCwgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Ml9wbmwsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wbmwgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTNfcG5sLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUE5MIiwgeGxhYiA9ICJQb3NpdGlvbiBpbiBMaXN0IiwgeWxhYiA9ICJWYWx1ZSIsIHlsaW0gPSBjKG1pbihjKG92ZXJhbGxfYXZlcmFnZV9NTV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wbmwpKSwgbWF4KGMob3ZlcmFsbF9hdmVyYWdlX01NX3BubCwgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wbmwsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG5sLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BubCkpKSkKbGluZXMob3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJyZWQiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG5sLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImdyZWVuIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJ5ZWxsb3ciKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3BubCwgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJibHVlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAicHVycGxlIikKbGluZXMob3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wbmwsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAib3JhbmdlIikKCiMgQWRkIGxlZ2VuZApsZWdlbmQoImJvdHRvbWxlZnQiLCBsZWdlbmQgPSBjKCJNYXJrZXQgTWFrZXIiLCAiSW5mb3JtZWQiLCAiTm9pc3kgSW5mb3JtZWQgMSIsICJOb2lzeSBJbmZvcm1lZCAyIiwgIk5vaXN5IDMiLCAiTm9pc3kgNCIsICJOb2lzeSA1IiksIGNvbCA9IGMoImJsYWNrIiwgInJlZCIsICJncmVlbiIsICJ5ZWxsb3ciLCAiYmx1ZSIsICJwdXJwbGUiLCAib3JhbmdlIiksIGx0eSA9IDEsIGNleCA9IDAuOCkKYGBgCgpgYGB7cn0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIGF2ZXJhZ2VzIGZvciBlYWNoIHBvc2l0aW9uCmF2ZXJhZ2VfTU1fcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX0luZm9ybWVkX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQphdmVyYWdlX05vaXN5MV9wbmwgPC0gbWF0cml4KE5BLCBucm93ID0gMTAwLCBuY29sID0gMTApCmF2ZXJhZ2VfTm9pc3kyX3BubCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAxMDAsIG5jb2wgPSAxMCkKYXZlcmFnZV9Ob2lzeTNfcG5sIDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwMCwgbmNvbCA9IDEwKQoKIyBMb29wIHRocm91Z2ggZWFjaCBzaW11bGF0aW9uIChuKQpmb3IgKG4gaW4gMToxMCkgewoKICBNTV9wb3Nfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCA3XSkpLCAiLCAiKQoKICBJbmZvcm1lZF9wb3Nfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCA5XSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQxX3Bvc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDExXSkpLCAiLCAiKQogIAogIE5vaXN5SW5mb3JtZWQyX3Bvc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDEzXSkpLCAiLCAiKQogIAogIE5vaXN5MV9wb3Nfc2V0OCA8LSBzdHJzcGxpdChnc3ViKCJcXFt8XFxdIiwgIiIsIHVubGlzdChhZ2dyZWdhdGVkX3Jlc3VsdHNfOFtuLCAxNV0pKSwgIiwgIikKICAKICBOb2lzeTJfcG9zX3NldDggPC0gc3Ryc3BsaXQoZ3N1YigiXFxbfFxcXSIsICIiLCB1bmxpc3QoYWdncmVnYXRlZF9yZXN1bHRzXzhbbiwgMTddKSksICIsICIpCiAgCiAgTm9pc3kzX3Bvc19zZXQ4IDwtIHN0cnNwbGl0KGdzdWIoIlxcW3xcXF0iLCAiIiwgdW5saXN0KGFnZ3JlZ2F0ZWRfcmVzdWx0c184W24sIDE5XSkpLCAiLCAiKQogIAogICMgTG9vcCB0aHJvdWdoIGVhY2ggcG9zaXRpb24gKGkpCiAgZm9yIChpIGluIDE6MTAwKSB7CiAgICAjIEV4dHJhY3QgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgTU1fcG9zIDwtIHNhcHBseShNTV9wb3Nfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIEluZm9ybWVkX3BvcyA8LSBzYXBwbHkoSW5mb3JtZWRfcG9zX3NldDgsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoeFtpXSkpCiAgICBOb2lzeUluZm9ybWVkMV9wb3MgPC0gc2FwcGx5KE5vaXN5SW5mb3JtZWQxX3Bvc19zZXQ4LCBmdW5jdGlvbih4KSBhcy5udW1lcmljKHhbaV0pKQogICAgTm9pc3lJbmZvcm1lZDJfcG9zIDwtIHNhcHBseShOb2lzeUluZm9ybWVkMl9wb3Nfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5MV9wb3MgPC0gc2FwcGx5KE5vaXN5MV9wb3Nfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5Ml9wb3MgPC0gc2FwcGx5KE5vaXN5Ml9wb3Nfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIE5vaXN5M19wb3MgPC0gc2FwcGx5KE5vaXN5M19wb3Nfc2V0OCwgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyh4W2ldKSkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugb2YgVHJ1ZSBhbmQgRXhwZWN0ZWQgdmFsdWVzIGZvciB0aGUgaS10aCBwb3NpdGlvbgogICAgYXZlcmFnZV9NTV9wb3NbaSwgbl0gPC0gbWVhbihNTV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfSW5mb3JtZWRfcG9zW2ksIG5dIDwtIG1lYW4oSW5mb3JtZWRfcG9zLCBuYS5ybSA9IFRSVUUpCiAgICBhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5SW5mb3JtZWQxX3BvcywgbmEucm0gPSBUUlVFKQogICAgYXZlcmFnZV9Ob2lzeUluZm9ybWVkMl9wb3NbaSwgbl0gPC0gbWVhbihOb2lzeUluZm9ybWVkMl9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kxX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5MV9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kyX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5Ml9wb3MsIG5hLnJtID0gVFJVRSkKICAgIGF2ZXJhZ2VfTm9pc3kzX3Bvc1tpLCBuXSA8LSBtZWFuKE5vaXN5M19wb3MsIG5hLnJtID0gVFJVRSkKICB9Cn0KCiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIGF2ZXJhZ2UgZm9yIGVhY2ggcG9zaXRpb24gYWNyb3NzIGFsbCBzaW11bGF0aW9ucwpvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTU1fcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9JbmZvcm1lZF9wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9JbmZvcm1lZF9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5SW5mb3JtZWQxX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBuYS5ybSA9IFRSVUUpCm92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zIDwtIHJvd01lYW5zKGF2ZXJhZ2VfTm9pc3kxX3BvcywgbmEucm0gPSBUUlVFKQpvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BvcyA8LSByb3dNZWFucyhhdmVyYWdlX05vaXN5Ml9wb3MsIG5hLnJtID0gVFJVRSkKb3ZlcmFsbF9hdmVyYWdlX05vaXN5M19wb3MgPC0gcm93TWVhbnMoYXZlcmFnZV9Ob2lzeTNfcG9zLCBuYS5ybSA9IFRSVUUpCgojIFBsb3QgdGhlIG92ZXJhbGwgYXZlcmFnZXMKcGxvdChvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsYWNrIiwgbWFpbiA9ICJPdmVyYWxsIEF2ZXJhZ2UgUG9zaXRpb24iLCB4bGFiID0gIlBvc2l0aW9uIGluIExpc3QiLCB5bGFiID0gIlZhbHVlIiwgeWxpbSA9IGMobWluKGMob3ZlcmFsbF9hdmVyYWdlX01NX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX0luZm9ybWVkX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5SW5mb3JtZWQyX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5MV9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BvcykpLCBtYXgoYyhvdmVyYWxsX2F2ZXJhZ2VfTU1fcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDFfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCBvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kxX3Bvcywgb3ZlcmFsbF9hdmVyYWdlX05vaXN5Ml9wb3MsIG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTNfcG9zKSkpKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfSW5mb3JtZWRfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInJlZCIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeUluZm9ybWVkMV9wb3MsIHR5cGUgPSAibCIsIHBjaCA9IDE2LCBjb2wgPSAiZ3JlZW4iKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3lJbmZvcm1lZDJfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gInllbGxvdyIpCmxpbmVzKG92ZXJhbGxfYXZlcmFnZV9Ob2lzeTFfcG9zLCB0eXBlID0gImwiLCBwY2ggPSAxNiwgY29sID0gImJsdWUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kyX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJwdXJwbGUiKQpsaW5lcyhvdmVyYWxsX2F2ZXJhZ2VfTm9pc3kzX3BvcywgdHlwZSA9ICJsIiwgcGNoID0gMTYsIGNvbCA9ICJvcmFuZ2UiKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgiYm90dG9tbGVmdCIsIGxlZ2VuZCA9IGMoIk1hcmtldCBNYWtlciIsICJJbmZvcm1lZCIsICJOb2lzeSBJbmZvcm1lZCAxIiwgIk5vaXN5IEluZm9ybWVkIDIiLCAiTm9pc3kgMyIsICJOb2lzeSA0IiwgIk5vaXN5IDUiKSwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIiwgInllbGxvdyIsICJibHVlIiwgInB1cnBsZSIsICJvcmFuZ2UiKSwgbHR5ID0gMSwgY2V4ID0gMC44KQpgYGAKCgojIyBzZXQ5CgoKCiMjIHNldDEwCgoKCiMjIHNldDExCgoKCiMjIHNldDEyCgoKCiMjIHNldDEzCgoKCiMjIHNldDE0CgoKCiMjIHNldDE1CgoKCgoKCgo=